376 Commits
0.2.0 ... 0.6.2

Author SHA1 Message Date
4abf6642f7 setting a Winix Licence: 2 Clause BSD Licence
changed: version to 0.6.2



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@963 e52654a7-88a9-db11-a3e9-0013d4bc506e
2014-10-04 18:04:03 +00:00
e3284dcfbc fixed: winix incorrectly used config options: upload_dirs_chmod and upload_files_chmod
added: to config: upload_group
       a group name for newly uploaded files (and created necessary directories in the file system)




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@961 e52654a7-88a9-db11-a3e9-0013d4bc506e
2014-09-28 17:30:05 +00:00
f064ff6b3d added: htmltextstream escapes more characters now:
added characters:
          "  -> &#quot;
          '  -> ' (' but IE8 has a problem with ')
          10 -> 

          13 -> 
added: two ezc filters:
       fil_html_quote
          "  -> &#quot;
          '  -> ' (' but IE8 has a problem with ')
       fil_html_newline
          10 -> 

          13 -> 
changed: fun_subject.html uses <div class="winix_input_a"> now





git-svn-id: svn://ttmath.org/publicrep/winix/trunk@959 e52654a7-88a9-db11-a3e9-0013d4bc506e
2014-09-22 23:54:24 +00:00
bfa5d8cc05 changed: plugin jQuery File Upload has been updated to version 9.7.0
(changed 'upload' and 'rm' winix functions)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@958 e52654a7-88a9-db11-a3e9-0013d4bc506e
2014-08-06 20:14:10 +00:00
6614919c13 added: possibility to save a pid file
new config option: pid_file (a full path to a pid file)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@957 e52654a7-88a9-db11-a3e9-0013d4bc506e
2014-08-04 21:11:14 +00:00
8379acdb7f fixed: item content should not be escaped in 'raw' mode
(it was not escaped only when execute bits were set)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@956 e52654a7-88a9-db11-a3e9-0013d4bc506e
2014-08-03 18:33:07 +00:00
160ddc258d added: to htmlfilter: the filter is able to recognize a special tag, default called: <nofilter>
content between <nofilter>...</nofilter> will not be filtered



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@955 e52654a7-88a9-db11-a3e9-0013d4bc506e
2014-06-18 23:18:28 +00:00
01892d2766 added: flag has_pass to User structure
if false that means the user has not set a password yet 
       (this can be used by a plugins to create a new account without a password set)
       in order to login the user first has to set a new password
       (this can be done from a some kind of activation link send via email etc)
       



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@954 e52654a7-88a9-db11-a3e9-0013d4bc506e
2014-06-07 11:20:44 +00:00
222955a2e7 fixed: in Synchro: we should have a table (map) of reference counters
each one for each thread
fixed: on Linux: pthread mutexes by default behaves differently than on FreeBSD
       we have to set PTHREAD_MUTEX_ERRORCHECK attribute 
       when creating a mutex
       



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@953 e52654a7-88a9-db11-a3e9-0013d4bc506e
2014-02-14 11:20:22 +00:00
37b22c3559 added: some debug logs to export plugin
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@952 e52654a7-88a9-db11-a3e9-0013d4bc506e
2014-02-12 22:32:06 +00:00
afbd522362 fixed: in Makefile: 'cp' in Linux behaves differently
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@951 e52654a7-88a9-db11-a3e9-0013d4bc506e
2014-02-12 20:49:50 +00:00
a4bed3ab14 fixed: compiling on Debian with GCC 4.8
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@950 e52654a7-88a9-db11-a3e9-0013d4bc506e
2014-02-12 17:21:42 +00:00
7468e7a36c added: namespace Winix over all *.h/*.cpp files
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@948 e52654a7-88a9-db11-a3e9-0013d4bc506e
2014-02-12 16:30:49 +00:00
145445c713 changed: now we use curl to fetch a page from the special thread when winix quits
(before we were using BSD's fetch)
fixed:   we didn't use FCGX_Finish_r() on the request made from the special thread
         so the thread hangs (now we can use pthread_join correctly from the main thread)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@947 e52654a7-88a9-db11-a3e9-0013d4bc506e
2014-02-11 21:00:32 +00:00
7fa9314c6b changed: in ClearOutputStreams() referencing 'config' only if not null
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@946 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-12-23 03:29:33 +00:00
5d37b6c6ae fixed: winix incorrectly sent the binary stream
headers and cookies were not sent
       (instead of headers the content was sent, so the client's browser was unable to open it correctly)
added: standard http headers are added by winix only if there are not such headers already
       e.g. if a plugin adds "Content-Type" header then winix will not overwrite it 
       (headers names are case sensitive)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@945 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-12-19 17:19:47 +00:00
fe1f84e29d added: -O0 -g for CXXFLAGS for temporarily debugging
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@944 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-12-18 12:13:28 +00:00
83e27a6653 fixed: problem with building
added #include <utility> to App (for std::move)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@943 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-12-09 16:03:45 +00:00
ee9c68b04e added: generating Content-Length header when text answer is sent to the client
added:   now we are able to use the html filter for the whole out_streams (when ajax is used the output is filtered too)
         splitted FilterCompressSend() function -- first we are making the filtering
         (after filtering we know the size of the content to send)
added:   to Compress:
         Compressing(const char * source, size_t source_len, BinaryPage & out_stream, int encoding);
changed: some refactoring in App




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@942 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-12-04 01:21:57 +00:00
c04874397b fixed: security vulnerability in 'ln' winix function
a user could create a hardlink to any file and the new link 
       had user_id, group_id and permissions the same as for new generated files,
       this allowes to overwrite any existing file in the filesystem,
       now user_id, group_id, permissions are the same as from the oryginal file



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@941 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-12-03 12:33:41 +00:00
375604edd6 removed: Request::debug all stream used for debugging info
some environment variables were put there
removed: config variable: debug_info
removed: Request::role (responder, authorizer)
         now we have only one role: responder
added:   new config variables:
         log_env_variables (default false) - when true then fastcgi environment
         variables are logged to the log file
         log_http_answer_headers (default false) - when true all http headers
         created by winix ale logged (note that the www server can add/adjust other headers)
changed: some refactoring in Request struct
changed: CookieTab to std::map<std::wstring, std::wstring>
         beforehand std::string was used
         (changed CookieParser as well)
changed: Request::SetCookie() to AddCookie()
added:   Request::out_headers (a PT::Space struct)
         http headers (without cookies) send back to the client
added:   Request::out_cookies (a PT::Space struct)
         cookies send to the client
changed: App class to use Request::out_headers and Request::out_cookies
         some SendHeaders...() methods were renamed to PrepareHeaders...()
         and they create output in Request::out_headers first (and out_cookies)
         and later it is sent
added:   two plugin messages:
         // http headers (without cookies) were created and are ready to send
         // here you can make some changes to them
         // in p1 you have a pointer to the PT::Space (Request::out_headers)
         #define WINIX_PREPARE_TO_SEND_HTTP_HEADERS		31070

         // http cookies were created and are ready to send
         // here you can make some changes to them
         // in p1 you have a pointer to the PT::Space (Request::out_cookies)
         #define WINIX_PREPARE_TO_SEND_HTTP_COOKIES		31080
added:   config variable:
         // how many output streams do we have in Request class
         // default: 16 (64 maximum)
         size_t ezc_out_streams_size;




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@940 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-11-29 21:39:23 +00:00
3e32f3784f removed: -O0 -g from production Makefile
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@939 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-11-25 23:44:01 +00:00
5c4a54d998 added: -O0 -g to the production Makefile
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@938 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-11-25 23:37:52 +00:00
3af3ac3f6f removed: ezn patterns for rawcontent and ajaxcontent:
index_rawcontent.html, index_ajaxcontent.html
         now we have out_streams in Request and some special
         keyword in ezc templates for sending content to the 
         specified streams
changed: the way how winix answers to the client's browsers:
         info from Request class:
	                                   winix answer send to the client's browser
	                                                       |
	                                                       |
	                                          depending on send_bin_stream
	                               -------------------------------------------------
	                               |                                               |
	                          text answer                                     binary answer
	                               |                                               |
	                   depending on return_json                          sending out_bin_stream
	             ------------------------------------
	             |                                  |
	       normal request                     ajax request
	             |                                  |
	   sending out_streams[0]           depending on return_info_only
	                              ------------------------------------------------------
	                              |                                                    |
	                 generating JSON object from:                   generating JSON object only from info
	                 out_streams and info, e.g.:                    e.g.:
	                 {                                              { info object serialized here }
	                  "stream_1": "some html content",
	                  "stream_2": "some other html content",
	                  "info": { info object serialized here }
	                 }
	                 note that out_streams[0] is not sent
	                 in JSON answers
	
	




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@937 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-11-14 20:59:23 +00:00
d801f53154 changed: now we are using the C++ 11 language (-std=c++11) and we are using
the clang compiler by default
changed: Makefile files have been a little cleaned
         the main Makefile now will not compile winix and winix.so if there
         were not any changes to source files (it's faster)
         (added Makefile.dep in the global directory with list of all source/header files)
changed: winix version to 0.5.5




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@933 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-10-15 21:57:51 +00:00
a6b06f82e9 fixed: compiling in the clang (new version of c++ std lib)
(added some header files)
added: three messsages in ticket plugin:
       // send by showtickets winix function when tickets are loaded (and sorted)
       // in p1 you have a pointer to the ticket tab: std::vector<Ticket::Ticket> (include "ticket.h")
       // in p2 you have a pointer to the sort tab:   std::vector<Item*>
       // those tables don't have to be equal in size (in the case when there is no some tickets in the database)
       #define WINIX_PL_TICKET_TICKETS_LOADED                 4106
       
       // a new ticket has been added
       // in p1 you have a pointer to the Ticket::Ticket structure (include "ticket.h")
       // in p2 you have a pointer to the Item structure
       #define WINIX_PL_TICKET_ADDED_NEW                              4107
       
       // a ticket has been changed
       // in p1 you have a pointer to the Ticket::Ticket structure (include "ticket.h")
       // in p2 you have a pointer to the Item structure
       #define WINIX_PL_TICKET_CHANGED                                        4108

added: two ezc functions for tickets:
       ticket_does_param_id_have_value()
       tickets_tab_does_param_id_have_value()
       (they take two integer arguments -- testing whether a specified param_id has the given value)
changed: some more minor additions in tickets templates




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@932 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-10-10 11:59:21 +00:00
b7f3f84080 changed: in 'showtickets' winix function
now tickets are sorted by the sort_index and then by date
changed: html in 'sort' winix function (added items' subjects to the item lists)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@931 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-07-08 14:42:14 +00:00
26715bdd4c changed: html for 'upload' winix function
all static files (css/js) are downloaded from our server now



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@930 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-07-02 07:14:19 +00:00
083fa7857f fixed: in notify/notify.cpp: a correct locale id should be taken
(we were not able to send: a mail with an activation link and 
        a mail with the reset password link when we didn't have a locale with id 0 loaded)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@929 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-05-16 21:02:17 +00:00
9ffda3e070 changed: in passwd: a redirect make only if a password has been changed
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@928 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-05-16 20:11:27 +00:00
81160dbbe9 fixed: a passwd winix function should allow a non loged person to reset his password (permission fix)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@927 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-05-16 20:08:07 +00:00
7c266b85e2 added: winix function 'account'
code for activating an account has been moved here from Pw
changed: the form for reseting a user's password has been moved
         to 'passwd' winix function (it was in Pw before)




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@926 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-05-16 19:26:44 +00:00
48cdca7549 changed: in fun_gallery.html: added js code to get the proper image id from url
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@925 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-05-14 08:37:22 +00:00
1c401eae3b added: to Rm function:
bool Rm::RemoveFileOrSymlink(long item_id, bool check_access)
added: in ticket plugin: possibility to remove a file/image
       (not finished yet)




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@924 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-05-06 07:23:44 +00:00
0e9eb30b5d added: some ezc function to ticket plugin:
ticket_param_value_for_param_id
       tickets_tab_param_value_for_param_id
       tickets_tab_conf_tab_param_name
       tickets_tab_conf_tab_file_tab
       tickets_tab_conf_tab_file_tab_index
       tickets_tab_conf_tab_file_tab_path
       tickets_tab_conf_tab_file_tab_itemid
       tickets_tab_conf_tab_file_tab_meta




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@923 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-04-24 01:21:19 +00:00
c10c9393c0 changed: plugin 'export': export winix function
the checkbox is now selected when we want to export static files too 
         (default it is not checked)
         



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@922 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-04-17 00:37:39 +00:00
8705b3437c fixed: imgcrop winix function should load only images
(when called in a directory)
added: to reload winix function:
       reloading (clearing) the cache from 'menu' plugin
added: to 'menu' plugin
       possibility to read 'meta' information from files 
       third argument 'withmeta' to menu_dir_tab ezc function
       e.g. [for menu_dir_tab "/directory" "..." "withmeta"]...[end]
       and some ezc functions to retrieve the meta values




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@921 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-04-16 09:51:36 +00:00
aed891764a added: to config: HasValue() methods
for checking if a value exists (useful for checking lists -- they don't have to be copied out)




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@920 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-04-02 22:24:30 +00:00
495499d12f added: a new winix function: imgcrop
for cropping images (and thumbnails)
       www.domain.com/dir/file.jpg/imgcrop  -- crop an image
       www.domain.com/dir/file.jpg/imgcrop/thumb  -- crop an image's thumbnail
       www.domain.com/dir/file.jpg/imgcrop/newthumb  -- crop and create a new thumbnail (from an original image)
       www.domain.com/dir/imgcrop -- show images' list with above options
added: to Image class: some methods for cropping




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@919 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-03-29 22:03:28 +00:00
8d9a021eab changed: when there is reqtype:json parameter and there is not set request.ajax_serializer
then we are using a generic json serializer
changed: we are sending the application/json header when returning an json string
added:   to config: log_server_answer (default false)
         when true we put the whole string (server's answer) to the log file
added:   to Request: use_200_status_for_not_found_and_permission_denied
         if this is true then if the server http code would be 403 or 404
         then we return 200 OK (useful when using ajax)
changed: System::RedirectTo() methods take as the last parameter: use_reqtype
         if this is true (default) then reqtype:type parameter is automatically added to the redirecting path
         




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@918 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-03-26 00:04:01 +00:00
be6e09c5af added: some ezc functions (item_tab_meta*)
added: some ezc functions (gallery_tab_meta*) to gallery plugin
added: to gallery plugin: a new gallery: Gallery version 1.2.9



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@917 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-02-26 11:49:22 +00:00
293e426ed4 fixed: plugin 'group'
Groups::ReindexGroups incorrectly read a field from a PT::Space (it used 'table' object directly)
       but the value was in 'table_single' 
       now we are using GetValue method



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@916 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-02-01 21:14:56 +00:00
60f2337b73 updated: paths in Makefile (prog subdirectory)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@915 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-01-19 16:31:15 +00:00
ce8152de2f changed: added 'logsave' when we are waiting for the database to be ready
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@913 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-01-19 10:10:17 +00:00
496a1979d2 fixed: in ticket plugin: editticket incorrectly used ticket_info->Clear() method
it was called after some objects were set consequently we were not allowed to edit a ticket



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@912 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-12-30 15:33:08 +00:00
fd698ca7b9 added: put the rebus answer into the log (when user has entered an incorrect answer)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@911 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-12-26 23:08:57 +00:00
b4b368d324 changed: Makefile dep
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@910 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-11-17 01:10:00 +00:00
825694c880 changed: in editticket: closing ticket is better to do via POST request
added:   a new message sent by editticket when closing a ticket:
         #define WINIX_PL_TICKET_CLOSED                                 4105
         // a ticket has been closed (closed button pressed)
         // in p1 you have a pointer to the Item struct
         // in p2 you have a pointer to the Ticket struct





git-svn-id: svn://ttmath.org/publicrep/winix/trunk@909 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-11-05 23:13:52 +00:00
32750a7d50 changed: ticket plugin: redirect type in editticket winix function (when there is 'close' parameter)
fixed:   prototype doesn't work with jquery (in ticket winix function)
         (prototype was loaded for lightbox)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@908 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-11-04 22:39:02 +00:00
0045c6c72c added: to Item struct: ameta (PT::Space)
admin meta information
added: option "a" to meta winix function
       editing admin meta information
changed: now if you don't have write access to an item
         you can't see the meta information
         previous if you had read access you could have seen them
added: in plugin ticket and thread
       support for 'closing' (ticket, thread)
       (this is only logic, we need some html yet)
added: some ezc function for getting meta/admin meta information
       (for the current item and the last directory)




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@907 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-11-04 21:01:02 +00:00
4809016b78 changed: html (slog.html)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@906 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-11-01 17:56:00 +00:00
6e2ba65524 changed: added 'check_abuse' parameter to Login::LoginUser
bool Login::LoginUser(const std::wstring & login, const std::wstring & password, bool remember_me,
                               bool use_ses_log, bool check_abuse)
         default 'false' -- it test the time between GET and POST and the rebus (if exists)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@905 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-10-27 11:17:52 +00:00
8033ac66c4 added: locales to fun_ipban.html
changed: cosmetic changes in IPBanContainer




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@904 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-10-27 10:14:07 +00:00
9ef3736989 added: to 'ipban' winix function:
possibility to remove a ban (or all bans)
added: to SessionManager: sorting of the ban list (in the second thread)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@903 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-10-27 09:03:49 +00:00
099dd55d0c added: IP ban mechanism (not finished yet -- we need a winix function to remove a ban)
now after some incorrent login attempts your IP can be banned or blocked
       (see new config variables)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@902 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-10-27 07:44:26 +00:00
53b4175d00 added: plugin message: WINIX_CHECK_PLUGIN_ACCESS
this message is sent before calling MakePost() or MakeGet()
       if you return false (which is default) you can prevent the access
       to the resource
       



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@901 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-10-17 19:52:55 +00:00
8aa6f08e08 updated: html (login and passwd)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@900 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-10-17 06:48:48 +00:00
c5024598cb updated: html/css (added div.winix to templates)
now we have winix.css in common/winix directory
         it is automatically loaded by index_head_functions_add.html


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@898 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-10-17 06:00:00 +00:00
dfcf6b29c0 added: to misc:
bool IsWhite(const wchar_t * str, bool treat_new_line_as_white)
       bool IsWhite(const std::wstring & str, bool treat_new_line_as_white)
       return true if the whole string is white (or an empty string)
added: global variable in admin environment for an user: "display_name"
       if defined it is used to display an user's name instead of its login
       it is used in: void print_user_name(Info & i, User & user);
       (tickets, threads, cat function etc)





git-svn-id: svn://ttmath.org/publicrep/winix/trunk@895 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-09-26 07:18:32 +00:00
7f48d1eb2e fixed: the way we check whether we need make the redirect from SSL to non SSL (or vice versa)
beforehand we didn't take into accout default winix functions



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@894 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-09-24 20:31:01 +00:00
eaa97995d2 fixed: we should check cur.request->function is not null (in5D app when testing ssl/nossl redirect)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@893 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-09-24 18:59:08 +00:00
14f997b844 added: need_ssl flag to FunctionBase
// try to use SSL
       // if in the config 'use_ssl' is true and 'use_ssl_only_for_logged_users' is true
       // then ssl is used only for logged users but sometimes there is a need to use
       // SSL even if noone is logged (for example for such functions like 'login' or 'adduser')
       // default: false
       // (this option is ignored if 'use_ssl' in the config is false)
       bool need_ssl;




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@892 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-09-24 18:38:35 +00:00
26e87b20b1 changed: in Crypt:
renamed Hash() -> HashBin()
         HashBin() is using a binary output from OpenSSL now
	 previously we are using the hex output and with the new OpenSSL version
         the text has additional characters and causes some problems
	 added: HashHex() - it is using the HashBin() and then converts the output
	 to hex format itself
	 



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@891 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-09-19 23:17:10 +00:00
5cdf6eff36 added: to ticket plugin:
some messges:
// 
#define WINIX_PL_TICKET_PREPARE_TO_ADD_TICKET  4103

// a next ticket will be displayed
// in p1 you have a pointer to the Item struct
// this is call from tickets_tab ezc function
#define WINIX_PL_TICKET_TICKETS_TAB_IS_NEXT            4104

methods:
void ticket_meta_value(Info & i)
void tickets_tab_meta_value(Info & i)






git-svn-id: svn://ttmath.org/publicrep/winix/trunk@890 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-09-15 23:34:25 +00:00
4ed535a3b7 added: to plugin ticket: message WINIX_PL_TICKET_LOAD_TICKETS
someone can send this message with a directory id
       and tickets will be loaded from the directory
       (and to display them you can use ezc functions)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@889 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-09-14 23:48:39 +00:00
da15323c2f added: to plugin thread: message WINIX_PL_THREAD_CAN_MAKE_REDIRECT
(similar as for ticket)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@888 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-09-14 07:14:54 +00:00
bd1f717b4c added: some methods in Dystem::Dirs (takes wchar_t * as an argument, now only std::wstring were)
changed: in plugin ticket: added message: WINIX_PL_TICKET_CAN_MAKE_REDIRECT
         it is sent at the end of POST request (editticket, createticket)
         if we can make a redirect (useful with AJAX)





git-svn-id: svn://ttmath.org/publicrep/winix/trunk@887 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-09-13 23:12:48 +00:00
72013046fc added: Lock class -- locking resources by using Synchro object
the destructor automatically calls Unlock()



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@886 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-09-11 23:46:00 +00:00
14ae19143f added: new ezc filter: fil_new_line_to_br
added: PutChar() methods to HtmlTextFilter and TexTextFilter



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@885 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-09-11 21:41:10 +00:00
d8260d8383 added: a new way: HEX format to saving/reading from PostgreSQL bytea columns
added: to Request:
       // binary page
       BinaryPage binary_page;

       // a compressed page ready to send to the client
       BinaryPage compressed_page;

       // if true then either page or ajaxpage will be sent to the client
       // if false then binary_page is sent
       // default: true
       bool use_text_page;

       BinaryPage is defined as (in requesttypes.h):
       typedef PT::TextStreamBase<char, 1, 4096> BinaryPage;

added: to Compress: now it can gets BinaryPage as arguments (input, output)
changed: winix version to: 0.5.0
added: in templates: TexTextStream class
       for taking input to the TeX typesetting system





git-svn-id: svn://ttmath.org/publicrep/winix/trunk@884 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-09-11 05:19:45 +00:00
9174555ff8 added: to config: log_time_zone_id (size_t) identifier
this is the time zone identifier used in log messages



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@882 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-09-06 17:50:14 +00:00
0c6ddc2218 added: 'subject' winix function is using WINIX_FILE_CHANGED message now (when changing a file's subject)
added: 'postredirect' global parameter (it can be a param or post value)
       you can use this parameter in a html POST form
       after processing the POST request winix will make a redirect to the value



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@881 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-09-04 20:24:42 +00:00
43b4075b16 added: ezc functions:
void dir_tab_subject(Info & i);
       void dir_tab_is_root(Info & i);
changed: in dir_tab_link:
         now it doesn't print the proto and base address - you should use [doc_base_url]




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@879 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-09-02 01:27:41 +00:00
8f8e44fee5 added: ezc functions:
void dir_is_no(Info & i)
       void dir_level_is(Info & i)
       void dir_last_url_is_no(Info & i)
       void item_no_is(Info & i)
       void item_url_is_no(Info & i)




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@878 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-08-26 22:30:25 +00:00
260c12894d added: to Request options used by ezc generators:
bool gen_trim_white;
       bool gen_skip_new_line;
       bool gen_use_special_chars;
added: new ezc filter: fil_csv_escape
       for escaping csv fields





git-svn-id: svn://ttmath.org/publicrep/winix/trunk@877 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-08-26 19:53:47 +00:00
adf273479a fixed: WINIX_RAW_POST_STRING should have a different id
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@876 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-08-19 14:25:43 +00:00
54480da405 added: WINIX_RAW_POST_STRING plugin message
this is the raw string sent in POST method (in p1 pointer there is a pointer to std::string object)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@875 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-08-19 14:24:24 +00:00
90261b2005 added: a new plugin message: WINIX_POST_PARAMS
raw POST parameters
       in p1 there is a pointer to std::string meaning a parameter's name
       in p2 there is a pointer to std::string value
       this is sent only from PostParser
       PostMultiParser (multipart/form-data html forms) doesn't send this messsage
       there is no a session set (session pointer is null)




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@874 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-08-19 13:50:58 +00:00
cc71c225a3 added: to DbBase:
bool EndTrans(bool everything_ok);



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@873 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-08-15 19:33:20 +00:00
e739f30088 fixed: when using Request::ajax_serializer then we should not use html filter
(the filter can be used before we make the json answer -- not implemented yet)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@872 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-08-12 18:23:48 +00:00
51d95b49a0 added: to Request:
// used as a JSON output (when ajax_serializer is defined)
       // it will be serialized and have at least:
       // 'content' string - the whole html content
       // 'http_status' integer - http status code (e.g. 200)
       PT::Space ajax;
 
       // if not null then the request will have a JSON as an output
       PT::SpaceToJSON * ajax_serializer;




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@871 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-08-08 16:04:48 +00:00
b5c155b927 added: export plugin
the possibility to export only non static files in a directory



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@870 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-08-03 10:55:14 +00:00
5a5fe1b0cc fixed: export plugin
I forgotten to add exporting a directory



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@869 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-08-03 10:24:24 +00:00
1c4e010fc1 I have forgotten to add: html/fun_export.html
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@868 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-08-03 09:39:25 +00:00
d8d523d983 added: 'export' winix function (export plugin)
exporting an item or the whole directory



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@867 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-08-03 09:25:17 +00:00
1c2589a2f2 added: to Log:
void LogBinary(const char * blob, size_t blob_len);
       void LogBinary(const std::string & blob);
       int LogLevel();



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@866 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-07-31 03:29:16 +00:00
1ec61ffa11 added: to Log:
operator<<(const PT::TextStreamBase<>())



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@865 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-07-25 10:28:41 +00:00
ca0a5c9cbe changed: upload html
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@864 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-07-15 18:20:22 +00:00
8dd31e737f changed: css
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@862 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-07-15 15:57:45 +00:00
e98cca7fbc updated: jquery upload plugin (upload winix function)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@861 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-07-15 15:49:48 +00:00
9830b0a50f added: to misc: UrlEncode which takes PT::TextStreamBase as an argument
added: to misc: QEncode which takes PT::TextStreamBase as an argument
added: to Locale: methods: IsKey, Get which takes PT::TextStreamBase as an argument




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@860 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-07-10 16:50:59 +00:00
f76a0ca3e9 added: some ezc functions in menu plugin
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@859 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-07-02 19:15:50 +00:00
5a6d1991ac changed: config.space is available public now
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@858 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-06-30 23:20:18 +00:00
329e2d8001 fixed: when there is no option "locale_files" in the config
the "en" should be loaded by default
added: LDFLAGS option to Makefiles
added: compilation with CLANG (some const objects should have been created with default cctor)




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@856 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-06-30 18:37:52 +00:00
403cca5aad rewritten: public interface in TemplatesFunctions::Locale
added a default parameter bool try_default_too = true to some methods: Get(), IsKey()
           added more methods for accessing by an internal index



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@854 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-06-27 23:21:43 +00:00
b8ff5d4cfc added: winix functions: locale, timezone
changed: time zones -- now we have the daylight saving time
       different for each year (start, end)
added: config option: time_zone_id (size_t)
       time zone identifier for not logged users
       or for newly created accounts
       those identifiers you can see in etc/time_zones.conf file
       or by using timezone winix function with 'a' parameter (timezone/a) (!!IMPROVE ME NOT IMPLEMENTED YET)
       default: 34 (Coordinated Universal Time UTC+00:00)
added: config option: locale_default_id (size_t)
       locale for not logged users
       or for newly created accounts
added: config option: locale_max_id (size_t)
       a maximum value of a locale identifier
       default: 100 (maximum: 1000)
       each locale files should have its own identifier (in "winix_locale_id" field)
       from zero to this value
added: config option: time_zone_max_id (size_t)
       maximum value of a time zone identifier
       time zones with an id greater than this will be skipped
       default: 130 (maximum: 1000)
removed: config option: locale_default



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@852 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-06-26 23:19:19 +00:00
54e6c07efc added: etc directory to Makefile install
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@850 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-06-22 23:41:12 +00:00
d11cda3577 added: a new directory "etc"
there'll be some generic config files for winix
added: a new file in etc directory: time_zones_file
       list of time zones (not finished yet -- daylight saving time is needed)
added: option to config: etc_dir
       a directory in which there are some config files
       used mainly when winix starts
       default: empty (means not for using)
added: option to config: time_zones_file
       a file in etc_dir with time zones info
       default: time_zones.conf
       this is a Space structure with all time zones
added: to system: TimeZones struct
       list of time zones read from etc/time_zones.conf



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@849 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-06-22 23:34:33 +00:00
abafb80caf added: time zone's names to locales
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@848 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-06-22 19:18:03 +00:00
e0dd85ca99 changed: making a redirect from SSL connection to non SSL
if either use_ssl in the config if false
         or if use_ssl_only_for_logged_users is true
         and a user is not logged
added:   base url redirect HTTP codes to the config
         // if current connection is without SSL and should be made through SSL
         // or if is via SSL and should be done in plain text
         // then we make a redirect
         // default: 303
         int use_ssl_redirect_code;

         // when the HOST_HTTP environment variable is not equal to '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.
         // set this option to false if you have multiple subdomains
         // default: false
         bool base_url_redirect;




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@847 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-06-07 00:26:37 +00:00
2c38fe180e added: new function for ezc templating:
void space_value_noescape(Info & i, PT::Space & space)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@846 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-06-05 21:31:12 +00:00
0d0f12b394 added: to Requst:
std::wstring * PostVarp(const std::wstring & var);
added: to misc:
       template<class CharType>
       bool Toa(unsigned/signed long/int value, CharType * buffer);
       some Toa methods which don't get the buffer len
       (the buffer has to be sufficient big)




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@845 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-06-04 17:51:43 +00:00
86d6c96aeb fixed: winix_subdomain ezc function
didn't print the subdomain
added: to rm winix function:
       bool Rm::RemoveItemByPath(const std::wstring & path, bool check_access)
fixed: in Upload winix function
       when uploading an image we have to get
       a mount point where the image is placed (parent dir)
       (it was cur->mount beforehand)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@844 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-06-03 02:14:33 +00:00
b605fb0a77 added: some ezc functions for subdomains:
void winix_subdomain(Info & i);
       void winix_subdomain_is_empty(Info & i);
       void winix_subdomain_is_not_empty(Info & i);
       void winix_subdomain_is(Info & i);




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@843 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-05-30 21:14:03 +00:00
ec773e5f29 added: TimeZone struct (core)
this class has information about a time zone (utf offset, daylight saving time)
       and methods for converting between UTC and local time
       structs User and Config has a TimeZone object
       System::ToLocal() and System::ToUTC() uses it for converting
       (depending whether a user is logged or not)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@842 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-05-30 19:04:18 +00:00
9d5d088b4a removed: in some places a dependencies to tm struct has left
removed: operator<<(tm&) from streams: textstream, log, dbtextstream, htmltextstream



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@840 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-05-27 18:11:34 +00:00
1b858f5782 removed: dependencies to 'tz' system structure
now we are using PT::Date from pikotools



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@839 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-05-26 23:04:49 +00:00
5b845f1d03 changed: in Request:
removed start_tm
         added start_date (PT::Date)
changed: in Session:
         removed: tm_time
         added: start_date (PT::Date)
         renamed: time -> start_time
         the same is for last_time
         now we have (last_time and last_date)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@838 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-05-24 21:09:37 +00:00
db9d381a43 added: to thread manager: names of the threads
the names are shown in the log file


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@837 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-05-19 17:04:33 +00:00
0df088e1e2 fixed: when demonizing there were some logs info put twice in the log file
now we first demonize (fork) and then open the log file
added: start adding support for PT::Date 
       we are using instead of tz system structure



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@836 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-05-19 15:14:35 +00:00
67099d5d06 changed: misc::OnlyDigit()
a comma is changed to a dot


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@835 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-05-12 20:30:34 +00:00
07e8e0c63c updated: to the new Space API (pikotools)
changed: in locale txt files:
         the '(' and ')' characters should be escaped '\(' and '\)'
         or the whole string should be quoted
added:   when parsing locale files we print the line number where there was a syntax error



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@833 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-05-12 16:37:44 +00:00
ecc89d8596 added: two plugin's messages
// a session is going to be removed
// it is called from session manager's thread (with lock/unlock)
#define WINIX_PREPARE_SESSION_TO_REMOVE          30027

// a session has been removed
// it is called from session manager's thread (with lock/unlock)
// in l1 you have the old session id
#define WINIX_SESSION_REMOVED                    30029




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@832 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-05-01 17:58:42 +00:00
c94b0311b6 updated: to the new Pikotools API
ConfParser is now SpaceParser
added:   to SessionManager
         Session * SessionManager::FindSession(long id)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@831 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-04-30 22:53:54 +00:00
fc33b4f882 added: a deadlock counter to Synchro class
now we can use Lock() more than one in the same thread
       and next Unlock() will recognize it
       sample:
       Lock(); // first lock -- resources locked
       Lock(); // second lock -- skipped (counter incremented)
       ...
       Unlock(); // first unlock -- skipped (because counter greater than zero)
       Unlock(); // second unlock -- actually unlocking


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@830 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-04-28 20:57:57 +00:00
1da1eef768 fixed: ThreadMenager should use Lock/Unlock in StartAll() method
added: Job class (system->job object)
       a general mechanism for jobs (by using PT::Space as a job structure)
       WINIX_JOB plugin message will be sent with a pointer to PT::Space



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@829 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-04-25 22:24:37 +00:00
baf10a9ba9 added: std::wstring Request::subdomain
support for subdomains



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@828 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-04-22 18:23:44 +00:00
bcea4f9464 fixed: base_url_redirect config option was not read from the config file
and was not used when checking for base url redirect
fixed: return values from plugins should be given in a special structure
       they were remembered in plugin object (ret_false, ret_true)
       and consequently were not thread safe
       now all plugin.Call() methods return PluginRes structure 
       in which there are ret_false and ret_true variables       
changed: small refactoring in AddUser winix function



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@827 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-04-22 13:30:07 +00:00
920290e9dc changed: permission to winix function 'who' and 'last'
(only logged users can use these functions)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@826 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-04-06 08:11:25 +00:00
1d83cf42a1 fixed: passwd winix funtion always changed a password for current user
(even if it was an administrator and has selected other people)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@825 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-03-30 06:44:38 +00:00
09bfdf9e77 added: two ezc functions:
void winix_postvar_value_is(Info & i);
       void winix_postvar_value_is_not(Info & i);



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@824 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-03-28 00:09:27 +00:00
e83fd91423 rewritten: sessions management
(Session, SessionContainer, SessionManager)
           now a Session object don't copy all fields in its copy constructor (only id)
           the rest fields are set after the object is inserted in SessionContainer
added:     after successfully login a session id is changed
added:     plugin.Call() methods with a first argument a pointer to a Session object



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@823 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-03-17 05:11:23 +00:00
70421b7bd1 reverted last commit (secure flag to cookie) with some info
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@822 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-03-15 17:50:19 +00:00
71ae70f670 added: to cookies: flag "; secure" if a connection is through SSL
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@821 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-03-15 10:43:29 +00:00
b1b3cea64e added: new plugin message: WINIX_PREPARE_USER_TO_LOGIN
a user will be logged in
        set PluginInfo::res to false (it is by default) to prevent logging the user
        directly after this message (if you do not return false)
        a WINIX_USER_LOGGED is sent
        in p1 you have a pointer to User struct
        (if at least one plugin returns false then the user will not be logged)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@820 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-03-14 20:25:30 +00:00
2712c57f15 changed: Makefile dep (dependencies from pikotools and tito were missing)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@819 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-03-12 20:30:36 +00:00
0b528c7225 added: to misc:
void OnlyDigit(StringType & s, bool allow_comma = true)
       removes all non-digit characters from a string


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@818 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-03-11 16:21:52 +00:00
b7007da5a9 fixed: misc: ValidateEmail() buffer overflow
added: notifications for resetting a user's password
       (there is no a winix function for this yet)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@817 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-03-09 22:56:54 +00:00
489310ba1c added: winix function: rmuser
changed: UGContainer<> now uses std::list as a storage
         (previously it was using std::vector with pointers)
removed: now we don't have the operator[] for UGContainer<>



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@816 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-03-09 02:36:25 +00:00
6c2c12fe5e added: html/fun_pw.html
default view for pw winix function


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@815 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-03-03 21:00:48 +00:00
e61f0db57e changed: export plugin:
password is stored as a string (in database)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@814 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-03-01 15:39:13 +00:00
3e3546a2fd fixed: plugin 'menu' incorrectly read directory items when the directory was en empty string
(the current directory should be used)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@813 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-03-01 15:14:46 +00:00
d2fa3b7171 corrected: in some places declarations of classes where mixed with struct (class/struct)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@812 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-02-29 22:52:55 +00:00
0e9f587591 added: to IsWhite (core/misc)
other unicode white characters
       25 characters -- without a new line character (10)
added: config option: account_need_email_verification
       if true then when creating an account a user has to provide
       his email address and a message with an activation link will be sent 
       back to him
added: 'pw' winix function (not finished yet)
       at the moment only one parameter 'activate'



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@810 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-02-28 21:09:44 +00:00
9208b15167 fixed: in winix function 'mv':
a recurrence loop - incorrect function was called (typo)
updated: to the new EZC api:
         templates from plugin menu
         templates from 'man' winix function


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@809 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-02-27 17:43:59 +00:00
a45fb30e0a rewritten: plugin 'menu'
now we have a cache for the plugin
           (this limits the number of database requests)
added:     to plugin 'menu'
           menu_dir_tab can have a 'current' parameter (first argument)
           (it uses the last path from the previous menu_dir_tab) 
changed:   updated to the new EZC api
added:     new message to plugins: WINIX_DIR_ADDED


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@808 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-02-24 12:09:38 +00:00
97c7edafd6 added: to misc:
UrlEncode() for char->wstring
         UrlEncode() for wstring->wstring
removed: Request::redirect_url_encoded flag
         the Request::redirect_to string should always be url-encoded
changed: in UrnEncode()
         now characters like '#' and '/' are not allowed in an url
         (will be url-encoded)
         


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@807 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-02-19 00:59:08 +00:00
1a51b1adc7 added: to config:
parameter: ezc_max_elements
          maximum number for elements through the whole template (ezc)
          default: 50000
       parameter: ezc_max_loop_elements
          maximum number of each [for] loop
          default: 5000 (from ezc generator)
added: to Request class:
       time_t start_time;
       tm start_tm;
       they are set when a request starts
       


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@806 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-02-17 05:19:24 +00:00
9d2be5c50d added: to misc:
void MaxSize(StringType & str, size_t max_size)
       if a string is larger than max_size then it is truncated to max_size characters


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@805 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-02-14 20:35:35 +00:00
f381f24402 fixed: in DbBase: removed:
DbBase::AssertQuery(const std::wstring & q)
       there was a recurrence calling (the method called itself)
       we don't need a method which get a wstring as an argument
added: DbBase::AssertQuery(const char * q, ExecStatusType t)
       DbBase::AssertQuery(const DbTextStream & query, ExecStatusType t)
       (AssertQuery with a second argument -- the same as to AssertResult)
       we don't have to use AssertQuery and AssertResult
       only one AssertQuery now
added: to plugins: two messages:
       // preparing a current user to logout
       // send from 'logout' winix function
       // !! IMPROVE ME this message can be sent when winix is making the shutdown
       // (for sessions which are not mark as 'remember me')
       // and when the SessionManager deletes a session (from the special thread)
       #define WINIX_PREPARE_USER_LOGGED_OUT          30610

       // a user has been logged out
       // send from 'logout' winix function
       // in l1 you have the old user_id
       // !! IMPROVE ME this message can be sent when winix is making the shutdown
       // (for sessions which are not mark as 'remember me')
       // and when the SessionManager deletes a session (from the special thread)
       #define WINIX_USER_LOGGED_OUT                          30620



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@804 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-02-12 14:52:52 +00:00
f6db85fcdb fixed: uninitialized variable in 'rm' winix function (in HasAccess method)
sometimes for directories the rm function could return 'access true' (even without 'r' parameter)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@803 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-02-10 00:50:05 +00:00
9687d5cd66 removed: operator<<(const PT::Space * space)
from textstream, log, dbtextstream, htmltextstream
added: compile option: -pthread



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@802 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-02-10 00:29:54 +00:00
6e2d00bc5b added: now we have a fourth part in permissions (guests)
e.g.: 07555 means:
           7 for owner
           5 for group
           5 for others
           5 for guests (not logged users)
added:     the sticky bit for directories
           e.g. permissions to a directory with a sticky bit set
           can be set to: 017555
rewritten: rm/mv winix functions to correctly understand the sticky bit
added:     Dir::FollowLink() recognizes ".." and "." now
           consequently System::FollowAllLinks recognizes it too
added:     umask -- calculating privileges for new files/directories
           all users have their own umask (in meta)
           and there is one in the config
           (for guests and when a user has not definied its own one)
removed:   mount option: only_root_remove



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@801 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-01-24 23:03:36 +00:00
5aaab89cd8 added: to locale: comparing lexicographically two characters/strings
int Compare(wchar_t c1, wchar_t c2);
       int Compare(const std::wstring & str1, const std::wstring & str2);
       
	   


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@800 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-01-21 20:51:13 +00:00
7407d24586 added: new ezc filter: fil_first_wordup
first character in a word is capitalized


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@799 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-01-21 17:13:00 +00:00
c9931da5ba fixed: plugin ticket: when a session expires all files from editticket were removed
it should be removed only those new added


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@798 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-01-21 12:29:44 +00:00
4311f06ade added: to TextStream<> and Log:
operator<<(const tm & tm_)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@797 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-01-19 20:50:42 +00:00
8b64b5d372 updated plugins/ticket templates functions
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@796 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-01-18 17:55:28 +00:00
631ca4f8a3 plugin ticket: rewritten templates ezc functions
(now images/files are working fine)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@795 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-01-17 22:54:41 +00:00
424618de38 added: to templates: an interface for getting information from Space
miscspace.h, miscspace.cpp
changed: plugin ticket
         now as a config we use a PT::Space struct
         (not finished yet, only 'integer', 'select' and 'progress' are done)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@794 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-01-16 10:12:38 +00:00
b2d3ca9543 now winix is using 'pikotools' (confparser, utf8, mainparser)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@792 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-01-12 02:24:08 +00:00
cb33f20a24 removing: confparser.h confparser.cpp
(moving to pikotools)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@791 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-01-11 11:32:01 +00:00
973d804db2 added: TextStream<> DbTextStream<> and HtmlTextStream<> have operator<<(Space&) now
added: to db: bool DbBase::AssertValueSpace(PGresult * r, int row, int col, Space & space, bool split_single)
added: environment variables for users
       User::env (of type Space) and
       User::aenv (of type Space) for admin variables (can be changed only by a super user)
added: winix function 'env'
       for changing User::env and User::aenv ('env' winix function with a 'a' parameter)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@790 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-01-08 03:59:51 +00:00
84eaa6b7b6 changed: rewritten templates/man
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@789 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-01-06 12:55:08 +00:00
f967a428ce added: winix function 'man'
displaying all winix functions and ezc templates functions


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@787 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-01-06 12:07:23 +00:00
543d464cbc changed: plugin 'menu': ezc funtion: menu_dir_tab
now we have two parameters: first is a path and second is: "images", "dirs", "files" or empty
          


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@786 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-01-02 02:05:12 +00:00
43470b2a41 forgotten to add html/index_rawcontent.html
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@785 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-12-17 22:02:49 +00:00
fa05e25a9d added: to config: 'content_type_header' parameter
the kind of "Content-Type" header send to the client
       if utf8 is enabled then 'charset=UTF-8' will also be appended
added: to templates: an index pattern for 'rawcontent'
       used when 'rawcontent' parameter is present
       by default the template has only one [content] ezc function
       useful in AJAX requests       


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@784 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-12-17 21:59:22 +00:00
fe2f1605f1 changed: core/misc: date format in Time() methods
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@783 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-12-14 20:35:19 +00:00
48b5c167bf added to db stream: DbTextStream::operator<<(const std::vector<long> & tabid)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@782 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-12-08 22:01:19 +00:00
08a0a36dfd changed: html (upload winix function)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@781 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-12-05 18:20:48 +00:00
d135c31ca0 added: to htmlfilter: html "col" tag is a 'simple' tag
added: ezc functions: winix_function_param_value_is and winix_function_param_value_is_not
       they take two arguments: param_name and param_value



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@780 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-12-04 19:34:39 +00:00
dce68221ad changed: plugin 'export'
rewritten changing of strings in html output
         (added support for https:// prefix)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@779 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-12-03 19:34:58 +00:00
93273bd470 changed: upload template
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@778 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-12-02 14:38:26 +00:00
92f7c11999 added: 'export' plugin can make use of some meta informations (from items)
additional export currently


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@777 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-12-01 20:45:06 +00:00
024ce8e73c added: a new index template: index_fullscreen.html
is chosen automatically when 'fullscreen' parameter is passed


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@776 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-12-01 18:54:09 +00:00
7902389ef1 changed: in plugin 'menu'
menu_dir_tab ezc functions can be nested now
         (not finished yet)
added:   'meta' winix function
         additional meta information for files and directories
         (not finished yet)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@775 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-11-25 04:51:55 +00:00
1e9ab2f805 added: to 'group' plugin: new ezc function: group_tab_is_current_link
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@774 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-10-30 23:47:43 +00:00
0550212b64 changed: GroupItem plugin has been renamed to Group
it's nearly finished
         now we are using three levels from Space (ConfParser)
         - group set
         - group
         - values
         


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@773 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-10-16 21:33:45 +00:00
c7b6ca67a2 changed: plugin messages:
WINIX_FILE_REMOVED and WINIX_DIR_PREPARE_TO_REMOVE
         now as a parameter we have a pointer to the Item struct
changed: export plugin now exports all files from a directory
         (in the future there'll be an option how the plugin should behave)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@772 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-09-30 01:33:42 +00:00
9dae2de2fa fixed: FunctionParser skipped a function name after an item (file) if the name was not a name for a function
it should report a 404 in such a case


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@771 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-09-28 22:24:24 +00:00
968593106e fixed: menu plugin: static files were not correctly skipped
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@770 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-09-26 06:56:35 +00:00
302cb0130d changed: menu plugin (static files are skipped)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@769 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-09-26 06:39:05 +00:00
89efaa790f changed: ConfParser -- now we can have a tree (spaces can have more than one level)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@768 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-09-26 05:40:26 +00:00
60f0e62c23 changed: we do not make a 'base redirect' when the request method is POST
changed: ConfParser -- now we have spaces (only one level)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@767 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-09-16 22:46:42 +00:00
f113e2ef31 changed: we should use SSL connection for such functions as:
adduser, login


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@766 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-09-14 09:56:00 +00:00
39923d6617 fixed: UGContainer<Type> used a std::vector<Type> and when a new item was inserted
then current iterators (and pointers) were invalidated
         now we are using std::vector<Type*>
         this caused some crashes when a new user was added by 'adduser' winix function
added:   plugin 'export' is able to upload files on a remote server now
         (not finished yet)
changed: Thumb class is now called: Image
         and we are able to resize images too
         (some new options in the config and in mount points)
added:   some new plugin messages



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@764 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-09-13 06:08:34 +00:00
72be443414 added: new flag: Request::using_ssl
true if the connections is encrypted by using SSL
changed: in BaseUrlRedirect
         we also check if the connection should use SSL 
         and if so then we make a redirect to "https://.."
changed: in 'static' mount points:
         if the request was e.g. "/styles/default.js?t=B49E5BQ"
         we should return a file "/styles/default.js" (without the "?..." part)
         additionally '#' character is checked



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@762 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-09-06 22:46:15 +00:00
392e8060ba added: some work in Export plugin
changed: in base redirect we are using 301 moved permanently status code now (was 303)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@761 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-09-05 15:38:09 +00:00
8c01b0f6c0 added: two tables to locales/substitute: smallleters, capitalics
added: locale.ToSmall(wchar_t), locale.ToCapital(wchar_t)
       now we are able to recognize other than ASCII characters
added: static/basic/winix.css with basic styles
removed: [include "item_options.html"] from html templates (fun_cat.html and others)




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@760 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-08-29 22:23:54 +00:00
b984475e49 fixed: index templates and 'change' templates were not cleared when 'reload' function was called
so wrong indexes have been assigned


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@759 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-08-27 03:12:33 +00:00
4f114ea33c added: ezc function: dir_has_parents
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@758 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-08-26 20:45:58 +00:00
5b8a9c0108 added: Patterns class (in templates)
ezc patterns are managed by this class
added: some work in groupitem plugin (not finished yet)
changed: ConfParser can read a string from memory now
         (need some testing yet)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@757 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-08-25 23:53:49 +00:00
ee6500ac65 added: some more orphans to polish default locale
added: new options to the config:
  url_proto: default: http://
  url_ssl_proto: default: https://
  use_ssl, use_ssl_static, use_ssl_common (whether or not to use SSL protocol)
  use_ssl_only_for_logged_users
  now we are able to use SSL encryption (https) together with normal connections
removed: config option: base_server




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@755 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-08-17 23:09:47 +00:00
3b2a1c3f25 added: new winix function: "sort"
sorting items in a directory (Item::sort_index is used)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@754 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-08-02 00:10:45 +00:00
4d87359aca added: Export plugin (not finished yet)
added:   ThreadManager
         all threads are connected to the ThreadManager
         they are started/stopped by the manager
changed: FunctionParser
         now we are parsing directly what is in URI
         (we were using GetParser beforehand)
         we are able to recognize ordinary URI scheme (with '?' and '#' characters)
         sample:
         http://domain.com/dir1/dir2/item/function?par1=val2&par2=val2#htmlanchor
         is the same as:
         http://domain.com/dir1/dir2/item/function/par1:val2/par2:val2#htmlanchor
         'htmlanchor' is put in Request::anchor field,
         and the default function can be used like this:
         http://domain.com/dir1/dir2/item?par1=val2&par2=val2#htmlanchor
         but there is not an equivalent in winix form
         e.g. http://domain.com/dir1/dir2/item/par1:val2/par2:val2#htmlanchor
         because 'par1:val2' would be treated as a function name
removed: GetParser
         now we don't have Request::get_tab structure
removed: CKEditorGetParser
         it is not needed now



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@752 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-07-28 22:18:10 +00:00
c37c1ff812 fixed: as we have insert_page ezc function now
we cannot delete ezc patterns when PatternCacher::GetPattern() method is called
       because we can delete a pattern which is in use
       now deleting is performed at the end of a request


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@751 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-07-15 02:09:02 +00:00
1812a2e9ad added: new plugin: menu
fixed: System::FollowAllLinks didn't check permissions to a file (only to a simlink or a directory)
added: new ezc function: insert_page
       now we are able to nest pages in pages



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@750 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-07-13 23:14:10 +00:00
ccc02f41bf added: we can use different redirect codes now
(int Request::redirect_type variable)
       we can set following integer values:
       300 - Multiple Choices
       301 - Moved Permanently
       302 - Found
       307 - Temporary Redirect
       303 - See Other
       default is 303 for all redirects



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@749 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-07-07 17:02:14 +00:00
eaf10c70b7 added: a new winix function: passwd
for changing your password
       or if you are a super user you can
       change a password for anyone
added: uname prints available plugins now



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@748 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-06-27 21:38:19 +00:00
06f42dd9cb changed: winix 'upload' function is a file manager now
we're using an jquery upload plugin
added:   Item struct has new rows: hash, hash_type, file_size, sort_index
added:   css mount parameter
         you can specify css files there, and javascript wysiwyg editors
         (ckeditor, tinymce) can make use of it
changed: post parsers can parse post variables with the same name
         (a postfix is added in such a case)
added:   common_dir parameter to the config
         this is a path to common directory (directory with common static files)
         it is needed to the 'css' mount parameter
         


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@746 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-06-24 20:53:21 +00:00
1d6ff73aad added: new winix function: mount
displaying all mount points
changed: struct Cur has now 'mount' pointer
         we should not use system->mounts.pmount now
         (it will be removed in the future)
changed: all mount point parameters are now propagated to childs mount points
         (if not defined there)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@745 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-06-21 21:24:49 +00:00
700a6fe643 updated index.html
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@742 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-06-19 21:07:23 +00:00
0a7432b059 added: SLog class -- session logger
messages are displayed in the browser (with locales)
changed: MountParser
         now if there is an error in a line -- the line is simply skipped
         


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@741 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-06-19 20:59:58 +00:00
b369fda1d9 deleted some log info
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@740 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-06-19 10:40:09 +00:00
c49c35cfbd added: a new mount type: static
some path in winix can be redirected to a specified static directory


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@738 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-06-14 23:45:42 +00:00
fb4742e165 added: nicedit: a new wysiwyg javascript editor
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@737 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-06-13 01:06:10 +00:00
fce45b93a2 fixed: users: flag 'super_user' was not correctly read ftom the database
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@736 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-06-09 23:00:00 +00:00
18ecd46a01 changed: when winix demonizes it creates a three new descriptors (0, 1 and 3)
pointing to /dev/null
added:   DbBase::AssertValueBin(PGresult * r, int row, int col, std::string & result)
         it reads binary (bytea) data
added:   DbTextStream can handle 'bool' types now
         (is puts 'true' of 'false' to the stream)
changed: now passwords can be stored either as plain text, a hash or can be encrypted
         with RSA
         currently we have following hashes:
         md4, md5, sha1, sha224, sha256, sha384, sha512
         we are using openssl to manage them
         (look at config options for more info)
changed: winix version to 0.4.7         
added:   class Run - you can run any program from os and send a buffer to its standard input
         and read what the program put on its standard output
added:   class Crypt (in System) - calculating hashes, and crypting/decrypting




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@734 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-06-09 21:22:08 +00:00
af8fbdae72 added: now winix will not log post parameters with 'pass' in names (at the beginning)
changed: only first few characters are logged (from POST)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@733 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-06-06 22:47:34 +00:00
c84997be30 small changes in Makefiles
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@731 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-06-06 20:35:56 +00:00
06551d6084 added: "str" "strnc" ezc functions
changed: ezc functions:
         "winix_false" to "false"
         "winix_true"  to "true"


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@730 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-04-26 17:19:08 +00:00
84145d7cc8 fixed: BBCODEParser incorrectly worked with the latest changes in HTMLFilter
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@729 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-04-16 11:27:54 +00:00
426beae796 renamed: config option 'html_filter_break_lines' to 'html_filter_break_word'
added:   config option 'html_filter_wrap_line'
         this wraps the whole line (line calculated with html tags as well)
changed: orphans (for html filter) are read from locale files now
         ('language_orphans' value )



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@728 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-04-16 08:42:22 +00:00
aadf12c7b3 added support for gzip compression
new config option: compression_encoding (integer)
 1  - use deflate if available (or raw deflate for Internet Explorer) or don't compress
 2  - use gzip if available or don't compress
 10 - prefer deflate -- use deflate (or raw deflate for IE) if both deflate and gzip are available
 20 - prefer gzip    -- use gzip if both deflate and gzip are available
 default: 20

		   


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@727 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-04-02 00:10:16 +00:00
1b60935d08 updated 'galleria' js plugin
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@726 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-04-01 16:30:14 +00:00
d68731fd55 fixed: thread plugin didn't correctly set the last item and replies (in 'thread' table)
when deleting an answer
added: ThreadInfo::Repair() method
       will be used by 'fsck' winix function       
added: plugins/groupitem 
       directory for a new plugin: 'groupitem'
       


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@725 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-03-23 17:54:53 +00:00
ba63c8c661 changed: removed Languages::Land enum
now we set the languages in the config file: option locale_files, sample:
  locale_files = ( en, pl )
it represents the name of locale files (those from locale_dir directory)
renamed config option: locale to locale_default


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@722 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-02-24 17:06:12 +00:00
15487b347f added ezc function: winix_function_param_is_not
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@721 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-02-22 04:14:26 +00:00
e7e90c6527 txt templates (a new line was missing)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@720 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-02-18 09:35:35 +00:00
ca5421347a fixed: a new created session doesn't have a correct time set
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@719 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-02-18 09:33:15 +00:00
c8a57f2046 added: to gallery plugin: gallery_theme() mount option
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@718 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-02-15 23:20:12 +00:00
583df13139 added: mount options: thumb_size(cx, cy)
size of a generated thumbnail (size in pixels)
added: plugin gallery: mount option gallery_type
       it can be:
       "lightbox"
       "galleria"
       "galleriathumb"


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@717 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-02-11 21:37:28 +00:00
5049961e17 added a new plugin: "gallery"
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@716 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-01-31 15:51:53 +00:00
18492e5d61 changed templates
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@715 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-01-27 14:35:25 +00:00
d4d9f89d1d changed: ticket templates
added: new plugin message (WINIX_END_REQUEST)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@714 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-01-27 12:24:45 +00:00
ecf19034ae added: winix uses now [filter] statement from ezc
added: notifications to threads (were temporarily disabled)
changed: templates in notifications



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@712 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-01-26 12:45:38 +00:00
00521c490e added: Q encoding in misc: QEncode()
for mails headers encoding



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@711 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-01-25 11:54:46 +00:00
3071df227a fixed: find_ticket_value (in plugins/ticket/templates.cpp)
should find the first item (can be more than one item with the same 'param')

fixed: added sorting tickets params in ReadTicketParams() (in plugins/ticket/ticketinfo.cpp)

fixed: plugin should have its own 'PluginInfo info' struct
a plugin's function can call another plugin's functions

added: removing tickets files/images

added: removing threads

changed: rm function will call WINIX_FILE_REMOVED now when deleting directories





git-svn-id: svn://ttmath.org/publicrep/winix/trunk@710 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-01-23 23:23:24 +00:00
915cabdf97 changed: added Cur structure
we have there two pointers: 
 Request * request;
 Session * session;
these are the current request and the current session


the session GC was moved to SessionManager (was in SessionContainer)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@708 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-01-23 14:15:30 +00:00
61ac29b2de added in ticket/templates.cpp binary search for tickets and tickets parameters
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@707 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-01-21 16:16:52 +00:00
ab84a5169e 'tickets' can use 'threads' now
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@706 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-01-20 18:37:51 +00:00
3fad25b8c8 moved some thread files to plugins/thread
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@705 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-01-05 21:44:19 +00:00
8154c403d8 we can create links (hard links, symbolic links) now
added winix functions: ln

winix function 'default' can be used without redirecting now

added new tickets types: TypeProgress, TypeString, TypeMultistring, TypeImages, TypeFiles
now tickets are combined with files
added winix functions: showtickets

fixed mountpoints:
when the default root mount was created its parameter table was empty
and it caused accessing to a non-existing objects

fixed logger:
modifiers (log1, log2, log3) were incorrectly treated
added modifier: log4 (debug info)

now we are moving threads to a new plugin 'thread'
created directory: plugins/thread
(not finished yet)




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@704 e52654a7-88a9-db11-a3e9-0013d4bc506e
2011-01-05 21:24:11 +00:00
bb83aed20d changed cat template
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@703 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-12-12 09:41:20 +00:00
600c9fc907 Thumb thread should check the exit signal
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@701 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-12-12 09:25:36 +00:00
5d09eb149c added a special thread for making thumbnails (thumb.h thumb.cpp)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@700 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-12-11 22:55:48 +00:00
e854fe3681 changed makefile
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@698 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-12-10 21:20:01 +00:00
36c8822e6c changed organization of static files
removed: item.auth item.auth_path
added:   item.file_path, item.file_fs, item.file_type
now the path to a static file is a relative path
added: thumbnails (not finished yet)
fixed: db didn't correctly return the number of deleted items /DelItem() method/




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@696 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-12-10 21:07:01 +00:00
9b29cce1a4 added a special default function: "-"
the proper default function will be selected automatically


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@695 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-12-07 18:18:45 +00:00
508f06339e added to config: session_max
how many sessions can be: default 1000000 (one milion)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@694 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-12-07 17:41:28 +00:00
0a9cdd2f15 added: gc for sessions (another thread)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@693 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-12-07 12:52:52 +00:00
7f77b6e3ec added ezc function: user_is_in_all_groups
changed: ezc function user_is_in_group (we can provide more than one group now)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@691 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-12-06 01:37:30 +00:00
9507b0b1ba changed Makefile
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@690 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-12-06 00:32:12 +00:00
ad9d6f4301 db: core/user table has only 'notify' column now (previous was cms_notify, thread_notify)
added: notifications for tickets (not finished yet)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@688 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-12-06 00:25:46 +00:00
b721fb6860 changed path templatesnotifiy/ to notify/
i forgot to add a file: notify/notify.cpp


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@687 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-12-02 02:36:49 +00:00
5f46cd2ea5 moved: templatesnotify -> notify
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@686 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-12-02 02:16:11 +00:00
35efed9fef - now the mess with threads has gone away
- we have a class BaseThread -- this is a base class -- we can inherit from it when
  creating a new thread
- others treads are correctly stopped (when signal comes) -- pthread_join
- we have a special thread only for signals



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@685 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-12-02 01:02:02 +00:00
08e53919e2 changed: updated to the new ezc api, this with O(1) when looking for a specific ezc function
changed: sessions are deleted at the end of a request (and only a few sessions)
         other sessions will be deleted after a next request


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@684 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-11-25 22:42:24 +00:00
933c8841ff added: uptime winix function prints how many sessions there are
changed: functions for text/numbers conversions
         int Toi(const std::string & str,  int base = 10);
         int Toi(const std::wstring & str, int base = 10);
         int Toi(const char * str,         int base = 10);
         int Toi(const wchar_t * str,      int base = 10);

         long Tol(const std::string & str,  int base = 10);
         long Tol(const std::wstring & str, int base = 10);
         long Tol(const char * str,         int base = 10);
         long Tol(const wchar_t * str,      int base = 10);

         template<class CharType>
         bool Toa(unsigned long value, CharType * buffer, size_t buf_len, int base = 10);

         template<class CharType>
         bool Toa(long value, CharType * buffer, size_t buf_len, int base = 10);

         template<class CharType>
         bool Toa(unsigned int value, CharType * buffer, size_t buf_len, int base = 10);

         template<class CharType>
         bool Toa(int value, CharType * buffer, size_t buf_len, int base = 10);

         const wchar_t * Toa(unsigned int value,  int base = 10);
         const wchar_t * Toa(unsigned long value, int base = 10);
         const wchar_t * Toa(int value,  int base = 10);
         const wchar_t * Toa(long value, int base = 10);

         void Toa(int  value, std::string & res,  int base = 10, bool clear = true);
         void Toa(long value, std::string & res,  int base = 10, bool clear = true);
         void Toa(int  value, std::wstring & res, int base = 10, bool clear = true);
         void Toa(long value, std::wstring & res, int base = 10, bool clear = true);

added:   HtmlTextStream class (files htmltextstream.cpp htmltextstream.h in templates)
         this is a special stream for automatically escaping html tags
	     



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@682 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-11-25 01:34:46 +00:00
518281e101 fixed: when signal comes winix properly exits
fixed:   when winix exits the session data were not properly destroyed (memory leak)
         we should set request.session pointer to each session when deleting sessions
         from session_container
         the session data were not properly destroyed when winix checked for 
         outdated sessions (and when it was removing them)
fixed:   performance (memcpy used too often)
         in some places there were reserve method used (on std::wstring/std::string objects)
         especially in AssignString() method and TextStream<> object
         if we add a new string we should check the new size
         and only call reserve() if the new size will be greater than existing one
         (plus some constant)
changed: fcgi objects moved to App class (from Request)
         now we use thread safe methods (e.g. FCGX_Accept_r)
added:   log_plugin_call option to the config
         default: false
         when true winix log when a plugin function is called
added:   winix parameter 'nostat' for not calculating statistics
         (useful when making performance tests)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@680 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-11-23 21:52:25 +00:00
515d4bab0d added ezc functions: winix_false, winix_true
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@679 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-11-22 01:12:46 +00:00
8e72a820dd added support for UTF-8
now the UTF-8 is a default charset


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@677 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-11-21 00:19:17 +00:00
f1f0fa34cb fixed: didn't compile
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@676 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-11-04 17:13:13 +00:00
5010ef93e8 added temporary debug info to Notify::ItemChanged() method
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@674 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-11-04 17:05:59 +00:00
e6679a3192 added a new winix function "vim" - an editor based on the WYMeditor
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@673 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-11-04 16:46:19 +00:00
7cf8d5d2d3 added: to htmlfilter: param tag has not an ending tag
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@672 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-10-25 18:00:23 +00:00
14198eca41 fixed: some log problems
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@671 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-10-24 19:31:43 +00:00
c6473f20dc now winix can demonize itself
parameter in the config: demonize (default: true)
 


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@669 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-10-24 19:26:54 +00:00
9c34cb5862 winix can drop privileges now (if started as the root)
added parameters to the config:
 user (string)
 group (string)
 additional_groups (bool)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@668 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-10-24 17:49:38 +00:00
149fd1629f rm function can remove tickets now
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@667 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-10-23 23:51:44 +00:00
c48241f78a fixed: there were mktime() used on some dirs Items
so sometimes the time of the dir was changed

now for converting tm into time_t use:
time_t Time(const tm & par);
time_t Time(const tm * par);
tm     Time(time_t par);
from core/misc.h

now winix internally use GMT time
only when printing it is converted to local user time
temporarily all users use the same local time (config: time_zone_offset)
(only logs are genereted with local system time)

added to system:
time_t LocalTime(time_t gmt_time);
tm     LocalTime(const tm * ptm);
tm     LocalTime(const tm & ptm);
they convert GMT time to local user time




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@666 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-10-23 23:12:47 +00:00
a1bee81a5b added 'stat' winix function
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@665 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-10-23 14:54:44 +00:00
1b053c03ba added: now plugin ticket uses a new horizontal table (plugins.ticket)
columns: dir_id, param, value
we are able to build complicated tickets 



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@664 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-10-19 00:31:20 +00:00
33057acd62 added ticket parser: plugins/ticket/ticketparser.h plugins/ticket/ticketparser.cpp
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@663 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-10-11 20:42:49 +00:00
07511a2eb0 fixed: DbBase::ConvertTime(tm) should not have been used in this way as it was
(it uses a static buffer)
       now DbTextStream can get tm struct so you don't have to use ConvertTime 


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@662 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-10-09 20:27:45 +00:00
69c634d53f added to core/misc:
bool EqualNoCase(const std::string & str1, const std::string & str2)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@660 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-10-01 23:20:03 +00:00
7bc17a9202 fixed: ticket sets a default function only for directories
fixed: reading a new url and subject in Functions::ReadItem()
added: tickets are sorted now (by date)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@659 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-30 20:58:20 +00:00
d94a08b991 moved: plugins/ticket/ticket.cpp -> plugins/ticket/templates.cpp
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@658 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-29 22:41:34 +00:00
a8b8c1feec tickets has been moved to a new plugin 'ticket'
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@657 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-29 21:24:34 +00:00
a589e5a090 added: TextStream a class similar to std::ostringstream
but with a Clear() method
       the dynamic allocated buffer can be easily reused
added: DbTextStream a special version of a stream
       used to create a database string query
       everything is escaped by default
added: DbBase a base class with some basic methods for communicating
       with the database
added: DbConn a class for managing connection to the database
changed: some refactoring in Db class       



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@655 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-18 00:51:12 +00:00
8b1db3304f creating winix/db directory (for the database class)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@654 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-16 10:20:20 +00:00
23aedd68b0 changed: mount points
mount type and mount fs are of type 'int' now
they can be added by plugins


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@652 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-12 23:33:27 +00:00
f48f08a98b changed: notification's template
added: notifications in tickets


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@650 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-07 23:54:01 +00:00
81dd88d25a fixed: there was missing html/fun_editticket.html template
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@649 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-09-05 18:58:24 +00:00
c92081d6e1 added: to stats plugin: microsoft bing searcher
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@648 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-08-28 21:19:30 +00:00
d6e80f5a23 fixed: plugins path
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@647 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-08-17 23:48:42 +00:00
37cf71234c changed makefile
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@645 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-08-17 23:33:27 +00:00
3b655f39e1 added: plugins_dir to config
small changes in makefiles


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@643 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-08-17 22:32:47 +00:00
eec0ddf466 added: method ConfParser::UseEscapeChar(bool escape)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@642 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-08-16 14:15:37 +00:00
ca4e53bb0f html code in editors (emacs, ckeditor...) is filtered now for normal users
(root is allowed to use any html code)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@641 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-08-14 17:56:07 +00:00
d9f2e91806 removed some debug logs from emacs
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@640 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-08-14 17:07:13 +00:00
7bfed62526 emacs didn't correctly report errors from db
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@639 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-08-14 16:55:16 +00:00
b63ac98f40 now winix waites for the database to be ready (when the operating system starts)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@638 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-08-14 16:23:18 +00:00
1e7d297c0e small changes in template winix function
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@637 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-08-14 14:45:25 +00:00
f3cd3b88b9 some improvement in templates
(now we have O(1) time for selecting the right html template)
added: winix function: template
for selecting a template for an item (file or dir)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@636 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-08-13 20:04:57 +00:00
9a199cd834 part II of rewriting
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@635 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-08-12 19:10:12 +00:00
c3fac2e83f changed method: void PostMultiParser::ReadContentToFileLoop()
previous version was not clean


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@634 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-08-11 15:47:44 +00:00
c7f6d2727c fixed: PostMultiParser incorrectly logged the size of input items (those which were not files)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@633 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-08-11 10:00:23 +00:00
9901c63ede removed some thread and ticket information from request
they are in FunThread and FunTicket classes now
added funtion FunUptime (I forgot about it)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@631 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-08-10 20:43:38 +00:00
76897b8a83 I have forgotten to create classes: Ckeditor and Tinymce (in functions)
git-svn-id: svn://ttmath.org/publicrep/winix/trunk@630 e52654a7-88a9-db11-a3e9-0013d4bc506e
2010-08-10 17:05:19 +00:00
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
85b678a8fb added: notifications to users' emails
(core/notify.h core/notify.cpp)
       templatesnotify directory
       all notifications are managed by a second thread


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@512 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-09-30 22:31:20 +00:00
9902ce2b78 added: support for output compression
git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@511 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-09-21 23:05:05 +00:00
394c7b22a2 changed: mount points
git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@508 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-06-07 22:17:07 +00:00
f99c993d96 added: column 'guest_name' to 'item' table
used when user_id is -1
added: mount parameters: thread_with_info, thread_with_header
added: function rm can remove threads



git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@506 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-06-07 02:40:27 +00:00
1eb42446f8 added: forum
added: mount params can have arguments (in parentheses)
added: mount params: withheader, withinfo, restrictcreatethread, only_root_can_remove,
       can_use_emacs_on(level), can_use_mkdir_on(level), 
added: table Item has 'subject' column now
removed: column 'subject' from table Content




git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@505 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-06-05 20:29:06 +00:00
3d001e7458 added: macro APPPREPARE
void AppFunction(int code);



git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@503 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-21 19:27:16 +00:00
2dd3fc7df8 changed: the way of building
core.a content.a templates.a confparser.a have gone away
	 there is only: cmslu.a now (in the global directory 'cmslu')
changed: the way of building
         in Makefile(s) we dont longer use explicitly a variable 'o = file1.o file2.o...'
	 it was put into Makefile.o.dep and is generated automatically 
         when 'make depend' is invoked
changed: some #include "..." directives were put from *.h to *.cpp files
         fewer dependences


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@501 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-04-21 20:50:55 +00:00
f46677dfc0 added: mount points have parameters now
added: to the database: table 'thread'



git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@499 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-04-20 23:49:28 +00:00
e94ccc86f8 fixed: a small problem in mountparser (it coused core dumped when there was a wrong mount point supplied)
fixed: 'default' funtion can take a directory now (there was an error early)


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@497 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-04-20 21:10:31 +00:00
e778903dab added: put info about logging out a user (to 'last' table) (when a session expires)
git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@496 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-04-20 20:22:35 +00:00
a1ea298a43 added: mount points
(reading /etc/fstab from db not working yet)
       core/mount.h
       core/mountparser.h
       core/mountparser.cpp
       core/mounts.h
       core/mounts.cpp
       content/thread.cpp
       content/createthread.cpp
       templates/thread.cpp       



git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@495 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-04-19 22:13:21 +00:00
7a4a8e0fe2 added: container LastContainer (lastcontainer.h lastcontainer.cpp)
it consists of last logged users
added: function 'last'


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@492 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-04-16 01:59:42 +00:00
bbaefd0f77 added: date_creation and date_modification to items
changed: function 'run' is using a template: fun_run.html
         there is: [item_run] called from this template


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@489 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-03-22 23:54:15 +00:00
951d0e8653 changed: DirContainer - uses std::list instead of std::vector as the main container
we do not have to rebuild indexes after deleting some items
added:   DirContainer::DelById(long id)
changed: Dirs::CheckRootDir() addes the root dir if there is no one
added:   Dirs::DeleteDir(long id) - deletes specified directory (and its contents)
         (from the cache and the database)
added:   Db::DelDirById(long id) - deletes a dir from the database 
         and its first children
added:   standard function rm can delete directories


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@487 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-02-06 13:12:03 +00:00
7d73d048c8 added: SessionContainer special container used by SessionManager
sessions are indexed by id and time (last used time)
changed: old sessions are deleted
       parameter: session_max_iddle in the config file
added: function 'who'


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@483 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-01-31 06:53:36 +00:00
a48766871d fixed: the way AppDb works (pg_conn and Connect method)
git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@482 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-01-27 18:43:44 +00:00
406cb4a619 changed: not logging (headers and body)
git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@480 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-01-26 21:21:07 +00:00
9418cc7a69 default.item has to be default.cpp
git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@479 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-01-26 21:08:42 +00:00
20f6fbcf84 changed: the way of building the cmslu
main Makefile is in an application directory
         in cmslu/ there are only libraries:
         core.a content.a confparser.a templates.a
added:   macros APPTEMPLATES APPFUNCTIONS
         defined in the application's Makefile
added:   PatternCacher
added:   cmslu function 'run'
         files which have exec permissions
         can be run (run is a default function)
         after read from the database the content is parsed
         into Ezc::Pattern object, this object is then cached
         in PatternCacher
added:   FunctionCodeParser - will be used to parse the code
         from standard functions (ls/cat/...)


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@475 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-01-26 20:49:28 +00:00
327f18525c changed: cmslu building
Makefile from cmslu/ builds only: confparser.a content.a core.a templates.a
         the proper *.fcgi file is created from an application
changed: all cmslu functions have english names (ls, emacs, etc)
fixed:   function: login/logout are placed where there are permissions


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@474 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-01-14 20:11:12 +00:00
8a0ea59c77 added: function: default
changes the default item in a directory


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@473 e52654a7-88a9-db11-a3e9-0013d4bc506e
2008-12-31 18:28:12 +00:00
f6ad846927 I forgot to commit content/mkdir.cpp
git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@472 e52654a7-88a9-db11-a3e9-0013d4bc506e
2008-12-31 13:40:23 +00:00
114b5724f8 added: function: mkdir
git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@471 e52654a7-88a9-db11-a3e9-0013d4bc506e
2008-12-31 13:36:46 +00:00
483 changed files with 83183 additions and 6265 deletions

169
Makefile
View File

@@ -1,53 +1,158 @@
CC = g++ # Makefile for GNU make
CFLAGS = -Wall -pedantic -g -I/usr/local/include -L/usr/local/lib
name = cmslu.fcgi
export CC include Makefile.dep
export CFLAGS
all: $(name) ifeq ($(OSTYPE), FreeBSD)
CXX = clang++
else
CXX = g++-4.8
endif
$(name): core content confparser templates ezc ifndef CXXFLAGS
g++ -o $(name) $(CFLAGS) core/core.a content/content.a confparser/confparser.a templates/templates.a ../ezc/src/ezc.a -lfcgi -lpq CXXFLAGS = -Wall -O0 -g -fPIC -pthread -std=c++11 -I/usr/local/include -I/usr/include/postgresql -DEZC_USE_WINIX_LOGGER -DEZC_HAS_SPECIAL_STREAM
endif
ifndef CXXWINIXINCLUDEFLAGS
# these flags are used for compiling and making dependencies (make depend)
# it's better to not using any system directories like -I/usr/local/include here
CXXWINIXINCLUDEFLAGS = -I../../winix -I../../../winix -I../../ezc/src -I../../../ezc/src -I../../tito/src -I../../../tito/src -I../../pikotools -I../../../pikotools
endif
ifndef LDFLAGS
LDFLAGS = -L/usr/local/lib
endif
# this macro is used in ezc's Makefile
EZC_USE_WINIX_LOGGER = yes
# for make install
winix_install_dir = /usr/local/winix
export CXX
export CXXFLAGS
export CXXWINIXINCLUDEFLAGS
export LDFLAGS
export EZC_USE_WINIX_LOGGER
all: winix.so plugins winix
core: FORCE winix.so: $(winix.src.files)
@cd core ; $(MAKE) -e @cd core ; $(MAKE) -e
@cd db ; $(MAKE) -e
@cd functions ; $(MAKE) -e
@cd notify ; $(MAKE) -e
@cd templates ; $(MAKE) -e
@cd ../ezc/src ; $(MAKE) -e
@cd ../tito/src ; $(MAKE) -e
@cd ../pikotools ; $(MAKE) -e
$(CXX) -shared -rdynamic -Wl,-whole-archive -o winix.so $(CXXFLAGS) $(CXXWINIXINCLUDEFLAGS) core/*.o db/*.o functions/*.o templates/*.o notify/*.o ../ezc/src/ezc.a ../tito/src/tito.a ../pikotools/utf8/utf8.a ../pikotools/space/space.a ../pikotools/mainparser/mainparser.a ../pikotools/date/date.a $(LDFLAGS) -lfcgi -lpq -lz -lpthread -lcurl -Wl,-no-whole-archive
templates: FORCE
@cd templates ; $(MAKE) -e
confparser: FORCE winix: winix.so $(winix.src.files)
@cd confparser ; $(MAKE) -e @cd main ; $(MAKE) -e
$(CXX) -o winix $(CXXFLAGS) $(LDFLAGS) main/*.o winix.so -lfcgi
content: FORCE
@cd content ; $(MAKE) -e
ezc: FORCE
@cd ../ezc/src ; $(MAKE) -e
clean: plugins: FORCE
@cd core ; $(MAKE) -e clean @cd plugins/stats ; $(MAKE) -e
@cd templates ; $(MAKE) -e clean @cd plugins/thread ; $(MAKE) -e
@cd confparser ; $(MAKE) -e clean @cd plugins/ticket ; $(MAKE) -e
@cd content ; $(MAKE) -e clean @cd plugins/gallery ; $(MAKE) -e
@cd ../ezc/src ; $(MAKE) -e clean @cd plugins/group ; $(MAKE) -e
rm -f $(name) @cd plugins/menu ; $(MAKE) -e
@cd plugins/export ; $(MAKE) -e
FORCE: FORCE:
clean:
@cd core ; $(MAKE) -e clean
@cd db ; $(MAKE) -e clean
@cd functions ; $(MAKE) -e clean
@cd templates ; $(MAKE) -e clean
@cd notify ; $(MAKE) -e clean
@cd plugins/stats ; $(MAKE) -e clean
@cd plugins/thread ; $(MAKE) -e clean
@cd plugins/ticket ; $(MAKE) -e clean
@cd plugins/gallery ; $(MAKE) -e clean
@cd plugins/group ; $(MAKE) -e clean
@cd plugins/menu ; $(MAKE) -e clean
@cd plugins/export ; $(MAKE) -e clean
@cd ../ezc/src ; $(MAKE) -e clean
@cd ../tito/src ; $(MAKE) -e clean
@cd ../pikotools ; $(MAKE) -e clean
@cd main ; $(MAKE) -e clean
rm -f winix.so
rm -f winix
depend: depend:
cd core ; $(MAKE) -e depend @cd core ; $(MAKE) -e depend
cd templates ; $(MAKE) -e depend @cd db ; $(MAKE) -e depend
cd confparser ; $(MAKE) -e depend @cd functions ; $(MAKE) -e depend
cd content ; $(MAKE) -e depend @cd templates ; $(MAKE) -e depend
cd ../ezc/src ; $(MAKE) -e depend @cd notify ; $(MAKE) -e depend
@cd plugins/stats ; $(MAKE) -e depend
@cd plugins/thread ; $(MAKE) -e depend
@cd plugins/ticket ; $(MAKE) -e depend
@cd plugins/gallery ; $(MAKE) -e depend
@cd plugins/group ; $(MAKE) -e depend
@cd plugins/menu ; $(MAKE) -e depend
@cd plugins/export ; $(MAKE) -e depend
@cd ../ezc/src ; $(MAKE) -e depend
@cd ../tito/src ; $(MAKE) -e depend
@cd ../pikotools ; $(MAKE) -e depend
@cd main ; $(MAKE) -e depend
echo -n "winix.src.files = " > Makefile.dep
find -E . -type f -regex ".*\.h|.*\.cpp" | xargs -I foo echo -n foo " " >> Makefile.dep
find -E ../ezc/src -type f -regex ".*\.h|.*\.cpp" | xargs -I foo echo -n foo " " >> Makefile.dep
find -E ../tito/src -type f -regex ".*\.h|.*\.cpp" | xargs -I foo echo -n foo " " >> Makefile.dep
find -E ../pikotools -type f -regex ".*\.h|.*\.cpp" | xargs -I foo echo -n foo " " >> Makefile.dep
install: all
# installing binaries
rm -Rf $(winix_install_dir)/bin
mkdir -p $(winix_install_dir)/bin
cp winix $(winix_install_dir)/bin
cp winix.so $(winix_install_dir)/bin
# etc configs
rm -Rf $(winix_install_dir)/etc
mkdir -p $(winix_install_dir)/etc
cp -rf etc/* $(winix_install_dir)/etc/
# html templates
rm -Rf $(winix_install_dir)/html
mkdir -p $(winix_install_dir)/html
cp -rf html/* $(winix_install_dir)/html/
# txt templates
rm -Rf $(winix_install_dir)/txt
mkdir -p $(winix_install_dir)/txt
cp -rf txt/* $(winix_install_dir)/txt/
# locales
rm -Rf $(winix_install_dir)/locale
mkdir -p $(winix_install_dir)/locale
cp -rf locale/* $(winix_install_dir)/locale/
# plugins
rm -Rf $(winix_install_dir)/plugins
mkdir -p $(winix_install_dir)/plugins
find plugins/ -name "*.so" | xargs -I foo cp foo $(winix_install_dir)/plugins/
# deleting subversion directories
find $(winix_install_dir) -type d -name ".svn" | xargs -I foo rm -fr foo
# removing privileges for others
find $(winix_install_dir) -exec chmod o-r,o-x,o-w "{}" "+"

1
Makefile.dep Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,29 +0,0 @@
o = confparser.o
all: confparser.a
confparser.a: $(o)
ar rcs confparser.a $(o)
.SUFFIXES: .cpp .o
.cpp.o:
$(CC) -c $(CFLAGS) $<
depend:
makedepend -Y. -f- *.cpp > Makefile.dep
clean:
rm -f *.o
rm -f *.a
include Makefile.dep

View File

@@ -1,3 +0,0 @@
# DO NOT DELETE
confparser.o: confparser.h

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();
}

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

View File

@@ -1,26 +0,0 @@
o = content.o privileges.o emacs.o login.o rm.o cat.o logout.o ls.o node.o
all: content.a
content.a: $(o)
ar rcs content.a $(o)
.SUFFIXES: .cpp .o
.cpp.o:
$(CC) -c $(CFLAGS) $<
depend:
makedepend -Y. -f- *.cpp > Makefile.dep
clean:
rm -f *.o
rm -f *.a
include Makefile.dep

View File

@@ -1,108 +0,0 @@
# DO NOT DELETE
cat.o: content.h ../templates/templates.h ../../ezc/src/ezc.h ../core/data.h
cat.o: ../core/misc.h ../core/log.h ../core/item.h ../core/error.h
cat.o: ../core/dirs.h ../core/db.h ../core/dircontainer.h ../core/user.h
cat.o: ../core/group.h ../core/ugcontainer.h ../core/users.h ../core/groups.h
cat.o: ../core/functions.h ../core/function.h ../core/request.h
cat.o: ../core/requesttypes.h ../core/session.h ../core/done.h
cat.o: ../core/getparser.h ../core/httpsimpleparser.h ../core/postparser.h
cat.o: ../core/cookieparser.h ../core/item.h ../core/db.h ../core/error.h
cat.o: ../core/user.h ../core/group.h ../core/users.h ../core/groups.h
cat.o: ../core/log.h ../core/misc.h ../core/function.h
cat.o: ../core/functionparser.h ../core/request.h ../core/data.h
content.o: content.h ../templates/templates.h ../../ezc/src/ezc.h
content.o: ../core/data.h ../core/misc.h ../core/log.h ../core/item.h
content.o: ../core/error.h ../core/dirs.h ../core/db.h ../core/dircontainer.h
content.o: ../core/user.h ../core/group.h ../core/ugcontainer.h
content.o: ../core/users.h ../core/groups.h ../core/functions.h
content.o: ../core/function.h ../core/request.h ../core/requesttypes.h
content.o: ../core/session.h ../core/done.h ../core/getparser.h
content.o: ../core/httpsimpleparser.h ../core/postparser.h
content.o: ../core/cookieparser.h ../core/item.h ../core/db.h ../core/error.h
content.o: ../core/user.h ../core/group.h ../core/users.h ../core/groups.h
content.o: ../core/log.h ../core/misc.h ../core/function.h
content.o: ../core/functionparser.h ../core/request.h ../core/data.h
emacs.o: content.h ../templates/templates.h ../../ezc/src/ezc.h
emacs.o: ../core/data.h ../core/misc.h ../core/log.h ../core/item.h
emacs.o: ../core/error.h ../core/dirs.h ../core/db.h ../core/dircontainer.h
emacs.o: ../core/user.h ../core/group.h ../core/ugcontainer.h ../core/users.h
emacs.o: ../core/groups.h ../core/functions.h ../core/function.h
emacs.o: ../core/request.h ../core/requesttypes.h ../core/session.h
emacs.o: ../core/done.h ../core/getparser.h ../core/httpsimpleparser.h
emacs.o: ../core/postparser.h ../core/cookieparser.h ../core/item.h
emacs.o: ../core/db.h ../core/error.h ../core/user.h ../core/group.h
emacs.o: ../core/users.h ../core/groups.h ../core/log.h ../core/misc.h
emacs.o: ../core/function.h ../core/functionparser.h ../core/request.h
emacs.o: ../core/data.h
login.o: content.h ../templates/templates.h ../../ezc/src/ezc.h
login.o: ../core/data.h ../core/misc.h ../core/log.h ../core/item.h
login.o: ../core/error.h ../core/dirs.h ../core/db.h ../core/dircontainer.h
login.o: ../core/user.h ../core/group.h ../core/ugcontainer.h ../core/users.h
login.o: ../core/groups.h ../core/functions.h ../core/function.h
login.o: ../core/request.h ../core/requesttypes.h ../core/session.h
login.o: ../core/done.h ../core/getparser.h ../core/httpsimpleparser.h
login.o: ../core/postparser.h ../core/cookieparser.h ../core/item.h
login.o: ../core/db.h ../core/error.h ../core/user.h ../core/group.h
login.o: ../core/users.h ../core/groups.h ../core/log.h ../core/misc.h
login.o: ../core/function.h ../core/functionparser.h ../core/request.h
login.o: ../core/data.h
logout.o: content.h ../templates/templates.h ../../ezc/src/ezc.h
logout.o: ../core/data.h ../core/misc.h ../core/log.h ../core/item.h
logout.o: ../core/error.h ../core/dirs.h ../core/db.h ../core/dircontainer.h
logout.o: ../core/user.h ../core/group.h ../core/ugcontainer.h
logout.o: ../core/users.h ../core/groups.h ../core/functions.h
logout.o: ../core/function.h ../core/request.h ../core/requesttypes.h
logout.o: ../core/session.h ../core/done.h ../core/getparser.h
logout.o: ../core/httpsimpleparser.h ../core/postparser.h
logout.o: ../core/cookieparser.h ../core/item.h ../core/db.h ../core/error.h
logout.o: ../core/user.h ../core/group.h ../core/users.h ../core/groups.h
logout.o: ../core/log.h ../core/misc.h ../core/function.h
logout.o: ../core/functionparser.h ../core/request.h ../core/data.h
ls.o: content.h ../templates/templates.h ../../ezc/src/ezc.h ../core/data.h
ls.o: ../core/misc.h ../core/log.h ../core/item.h ../core/error.h
ls.o: ../core/dirs.h ../core/db.h ../core/dircontainer.h ../core/user.h
ls.o: ../core/group.h ../core/ugcontainer.h ../core/users.h ../core/groups.h
ls.o: ../core/functions.h ../core/function.h ../core/request.h
ls.o: ../core/requesttypes.h ../core/session.h ../core/done.h
ls.o: ../core/getparser.h ../core/httpsimpleparser.h ../core/postparser.h
ls.o: ../core/cookieparser.h ../core/item.h ../core/db.h ../core/error.h
ls.o: ../core/user.h ../core/group.h ../core/users.h ../core/groups.h
ls.o: ../core/log.h ../core/misc.h ../core/function.h
ls.o: ../core/functionparser.h ../core/request.h ../core/data.h
node.o: content.h ../templates/templates.h ../../ezc/src/ezc.h ../core/data.h
node.o: ../core/misc.h ../core/log.h ../core/item.h ../core/error.h
node.o: ../core/dirs.h ../core/db.h ../core/dircontainer.h ../core/user.h
node.o: ../core/group.h ../core/ugcontainer.h ../core/users.h
node.o: ../core/groups.h ../core/functions.h ../core/function.h
node.o: ../core/request.h ../core/requesttypes.h ../core/session.h
node.o: ../core/done.h ../core/getparser.h ../core/httpsimpleparser.h
node.o: ../core/postparser.h ../core/cookieparser.h ../core/item.h
node.o: ../core/db.h ../core/error.h ../core/user.h ../core/group.h
node.o: ../core/users.h ../core/groups.h ../core/log.h ../core/misc.h
node.o: ../core/function.h ../core/functionparser.h ../core/request.h
node.o: ../core/data.h
privileges.o: content.h ../templates/templates.h ../../ezc/src/ezc.h
privileges.o: ../core/data.h ../core/misc.h ../core/log.h ../core/item.h
privileges.o: ../core/error.h ../core/dirs.h ../core/db.h
privileges.o: ../core/dircontainer.h ../core/user.h ../core/group.h
privileges.o: ../core/ugcontainer.h ../core/users.h ../core/groups.h
privileges.o: ../core/functions.h ../core/function.h ../core/request.h
privileges.o: ../core/requesttypes.h ../core/session.h ../core/done.h
privileges.o: ../core/getparser.h ../core/httpsimpleparser.h
privileges.o: ../core/postparser.h ../core/cookieparser.h ../core/item.h
privileges.o: ../core/db.h ../core/error.h ../core/user.h ../core/group.h
privileges.o: ../core/users.h ../core/groups.h ../core/log.h ../core/misc.h
privileges.o: ../core/function.h ../core/functionparser.h ../core/request.h
privileges.o: ../core/data.h
rm.o: content.h ../templates/templates.h ../../ezc/src/ezc.h ../core/data.h
rm.o: ../core/misc.h ../core/log.h ../core/item.h ../core/error.h
rm.o: ../core/dirs.h ../core/db.h ../core/dircontainer.h ../core/user.h
rm.o: ../core/group.h ../core/ugcontainer.h ../core/users.h ../core/groups.h
rm.o: ../core/functions.h ../core/function.h ../core/request.h
rm.o: ../core/requesttypes.h ../core/session.h ../core/done.h
rm.o: ../core/getparser.h ../core/httpsimpleparser.h ../core/postparser.h
rm.o: ../core/cookieparser.h ../core/item.h ../core/db.h ../core/error.h
rm.o: ../core/user.h ../core/group.h ../core/users.h ../core/groups.h
rm.o: ../core/log.h ../core/misc.h ../core/function.h
rm.o: ../core/functionparser.h ../core/request.h ../core/data.h

View File

@@ -1,38 +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 "content.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;
}
}

View File

@@ -1,256 +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 "content.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::SetDefaultFunction()
{
if( request.is_item )
{
request.pfunction = data.functions.GetFunction(Function::cat);
if( request.pfunction )
log << log3 << "Content: default function: " << request.pfunction->item.url << logend;
}
else
{
long default_item = request.dir_table.back()->default_item;
if( default_item == -1 )
{
request.pfunction = data.functions.GetFunction(Function::ls);
if( request.pfunction )
log << log3 << "Content: default function: " << request.pfunction->item.url << logend;
}
else
{
log << log3 << "Content: Default item: id: " << default_item << logend;
RedirectTo(default_item);
}
}
}
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 == Function::logout )
FunLogout();
else
if( request.pfunction->code == Function::cat )
FunCat();
else
if( request.pfunction->code == Function::ls )
FunLs();
else
if( request.pfunction->code == Function::emacs )
FunEmacs();
else
if( request.pfunction->code == Function::privileges )
FunPrivileges();
else
if( request.pfunction->code == Function::rm )
FunRm();
else
if( request.pfunction->code == Function::node )
FunNode();
}
void Content::MakePost()
{
if( !request.pfunction )
{
log << log1 << "Content: MakePost: no function" << logend;
request.status = Error::no_function;
return;
}
switch( request.pfunction->code )
{
case Function::emacs:
PostFunEmacs();
break;
case Function::privileges:
PostFunPrivileges();
break;
case Function::login:
PostFunLogin();
break;
default:
log << log1 << "Content: unknown post function" << logend;
break;
}
}
void Content::Make()
{
if( request.dir_table.empty() )
{
log << log1 << "Content: there is no a root dir" << logend;
return;
}
// request.status can be changed by function_parser
if( request.status == Error::ok )
{
if( DirsHaveReadExecPerm() )
{
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;
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;
}
}
}

View File

@@ -1,73 +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 headerfilecontent
#define headerfilecontent
#include <cstdlib>
#include <fcgiapp.h>
#include "../templates/templates.h"
#include "../core/request.h"
#include "../core/error.h"
#include "../core/misc.h"
#include "../core/db.h"
#include "../core/user.h"
#include "../core/function.h"
#include "../core/functionparser.h"
class Content
{
Templates templates;
void PrepareUrl(Item & item);
void SetDefaultFunction();
bool DirsHaveReadExecPerm();
void MakeStandardFunction();
void MakePost();
void FunCat();
void FunLogout();
void FunLs();
void FunEmacs();
void FunPrivileges();
void FunRm();
void FunNode();
void PostFunLogin();
void PostFunEmacsAdd();
void PostFunEmacsEdit(bool with_url);
void PostFunEmacs();
void PostFunPrivileges();
void RedirectTo(const Item & item);
void RedirectTo(long item_id);
public:
bool Init();
void Make();
};
#endif

View File

@@ -1,133 +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 "content.h"
void Content::PrepareUrl(Item & item)
{
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(), '_');
}
}
void Content::PostFunEmacsAdd()
{
request.session->done = Done::added_item;
request.is_item = true;
request.item.user_id = request.session->puser ? request.session->puser->id : -1;
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;
if( !request.HasWriteAccess(*request.dir_table.back() ) )
throw Error(Error::permision_denied);
request.session->done_status = db.AddItem(request.item);
}
void Content::PostFunEmacsEdit(bool with_url)
{
request.session->done = Done::edited_item;
if( !request.HasWriteAccess(request.item) )
throw Error(Error::permision_denied);
request.session->done_status = db.EditItemById(request.item, with_url);
}
void Content::PostFunEmacs()
{
try
{
// these old values are ignored (if exists)
request.item.url = request.PostVar("url");
request.item.subject = request.PostVar("subject");
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( request.is_item )
PostFunEmacsEdit(with_url);
else
PostFunEmacsAdd();
}
catch(const Error & e)
{
request.session->done_status = e;
}
if( request.session->done_status == Error::ok )
{
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.HasReadWriteAccess(*request.dir_table.back()) )
request.status = Error::permision_denied;
return;
}
// editing an existing item
if( !request.HasReadWriteAccess(request.item) )
{
request.status = Error::permision_denied;
return;
}
}

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, Tomasz Sowa
* All rights reserved.
*
*/
#include "content.h"
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;
}
log << log2 << "User " << login << " (id: " << user_id << ") logged" << logend;
if( request.is_item )
{
RedirectTo(request.item);
}
else
{
RedirectTo(*request.dir_table.back());
}
}
}
catch(const Error &)
{
}
}

View File

@@ -1,45 +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 "content.h"
void Content::FunLogout()
{
if( request.session->puser )
{
log << log2 << "User: " << request.session->puser->name << ", id: " << request.session->puser->id << " logged out" << logend;
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;
}

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, Tomasz Sowa
* All rights reserved.
*
*/
#include "content.h"
void Content::FunLs()
{
if( request.is_item )
{
// we're showing only the item
request.item_table.push_back( request.item );
return;
}
// we're showing the whole directory
Item item_ref;
item_ref.parent_id = request.dir_table.back()->id;
// !! zrobic inna metode, inny interfejs (jako parametr niech bierze parent_id), i zeby nie odczytywala contentu i subjectu (a moze tylko subject? przyda sie przy ls -l)
db.GetItems(request.item_table, item_ref);
}

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, Tomasz Sowa
* All rights reserved.
*
*/
#include "content.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);
}

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, Tomasz Sowa
* All rights reserved.
*
*/
#include "content.h"
void Content::PostFunPrivileges()
{
// !! narazie tylko dla plikow
if( !request.is_item )
return;
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( !request.CanChangeUser(request.item, user_id) )
throw Error(Error::cant_change_user);
if( !request.CanChangeGroup(request.item, group_id) )
throw Error(Error::cant_change_group);
if( !request.CanChangePrivileges(request.item, privileges) )
throw Error(Error::cant_change_privileges);
request.item.user_id = user_id;
request.item.group_id = group_id;
request.item.privileges = privileges;
request.session->done = Done::privileged_item;
request.session->done_status = db.EditPrivById(request.item, request.item.id);
}
catch(const Error & e)
{
log << log1 << "Content: FunChmod: Error: " << e << logend;
request.session->done_status = e;
}
if( request.session->done_status == Error::ok )
{
request.session->item = request.item;
request.session->done_timer = 2;
RedirectTo(request.item);
}
else
{
log << log1 << "Content: PostFunPrivileges: Error: " << static_cast<int>(request.session->done_status) << logend;
}
}
void Content::FunPrivileges()
{
if( !request.is_item )
{
// !! chwilowi tylko dla plikow
request.status == Error::item_required;
return;
}
// you must be an owner of the item (or a superuser)
// !! moze wykorzystac request.CanChangeUser() ?
if( !request.session->puser || (!request.session->puser->super_user && request.session->puser->id != request.item.user_id) )
{
request.status = Error::permision_denied;
return;
}
}

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, Tomasz Sowa
* All rights reserved.
*
*/
#include "content.h"
void Content::FunRm()
{
// !! narazie usuwanie tylko dla plikow
if( !request.is_item )
{
request.status = Error::permision_denied;
return;
}
if( !request.HasWriteAccess(*request.dir_table.back()) || !request.HasWriteAccess(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;
}
else
{
request.session->done_status = Error::db_no_item;
}
request.session->done = Done::deleted_item;
request.result = Request::redirect;
RedirectTo(*request.dir_table.back());
request.session->done_timer = 2;
}
else
{
if( request.IsParam("potwierdz") )
{
//request.result = Request::del_item_confirm;
}
else
request.result = Request::err404;
}
}

View File

@@ -1,26 +1,19 @@
o = data.o log.o sessionmanager.o requestcontroller.o dircontainer.o session.o main.o done.o request.o misc.o httpsimpleparser.o db.o error.o db_itemcolumns.o users.o config.o dirs.o groups.o function.o functionparser.o functions.o include Makefile.o.dep
all: $(o)
all: core.a
core.a: $(o)
ar rcs core.a $(o)
.SUFFIXES: .cpp .o
.cpp.o:
$(CC) -c $(CFLAGS) $<
%.o: %.cpp
$(CXX) -c $(CXXFLAGS) $(CXXWINIXINCLUDEFLAGS) $<
depend: depend:
makedepend -Y. -f- *.cpp > Makefile.dep makedepend -Y. $(CXXWINIXINCLUDEFLAGS) -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
clean: clean:
rm -f *.o rm -f *.o
rm -f *.a
include Makefile.dep include Makefile.dep

File diff suppressed because it is too large Load Diff

1
core/Makefile.o.dep Executable file
View File

@@ -0,0 +1 @@
o = acceptbaseparser.o app.o basethread.o bbcodeparser.o compress.o config.o crypt.o dircontainer.o dirs.o groups.o htmlfilter.o httpsimpleparser.o image.o ipbancontainer.o item.o job.o lastcontainer.o loadavg.o lock.o log.o misc.o mount.o mountparser.o mounts.o plugin.o plugindata.o postmultiparser.o rebus.o request.o run.o session.o sessioncontainer.o sessionmanager.o sessionparser.o slog.o synchro.o system.o threadmanager.o timezone.o timezones.o user.o users.o

148
core/acceptbaseparser.cpp Executable file
View File

@@ -0,0 +1,148 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <cstdlib>
#include "acceptbaseparser.h"
namespace Winix
{
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);
}
}
} // namespace Winix

80
core/acceptbaseparser.h Executable file
View File

@@ -0,0 +1,80 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_acceptbaseparser
#define headerfile_winix_core_acceptbaseparser
#include <string>
namespace Winix
{
// 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;
};
} // namespace Winix
#endif

118
core/acceptencodingparser.h Executable file
View File

@@ -0,0 +1,118 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_acceptencodingparser
#define headerfile_winix_core_acceptencodingparser
#include "acceptbaseparser.h"
#include "log.h"
namespace Winix
{
class AcceptEncodingParser : public AcceptBaseParser
{
public:
bool AcceptDeflate()
{
return accept_deflate;
}
bool AcceptGzip()
{
return accept_gzip;
}
void ParseAndLog(const char * str)
{
Parse(str);
if( accept_deflate || accept_gzip )
{
log << log3 << "AEP: ";
if( accept_deflate )
{
log << "accept deflate";
if( accept_gzip )
log << ", ";
}
if( accept_gzip )
log << "accept gzip";
log << logend;
}
}
private:
void Init()
{
accept_deflate = false;
accept_gzip = false;
}
void Param(const std::string & param, double q)
{
if( param=="deflate" && q!=0.0 )
{
accept_deflate = true;
}
if( param=="gzip" && q!=0.0 )
{
accept_gzip = true;
}
}
bool accept_deflate;
bool accept_gzip;
};
} // namespace Winix
#endif

1766
core/app.cpp Executable file

File diff suppressed because it is too large Load Diff

238
core/app.h Executable file
View File

@@ -0,0 +1,238 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2010-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_app
#define headerfile_winix_core_app
#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 <fcgiapp.h>
#include "config.h"
#include "system.h"
#include "mounts.h"
#include "request.h"
#include "synchro.h"
#include "sessionmanager.h"
#include "db/db.h"
#include "functions/functions.h"
#include "templates/templates.h"
#include "compress.h"
#include "postparser.h"
#include "cookieparser.h"
#include "postmultiparser.h"
#include "acceptencodingparser.h"
namespace Winix
{
class App
{
public:
App();
bool InitFCGI();
bool DropPrivileges();
bool Init();
void Start();
void Close();
void LogUserGroups();
bool Demonize();
void SetStopSignal();
bool WasStopSignal();
bool Lock();
void Unlock();
void StartThreads();
void WaitForThreads();
// configuration read from a config file
Config config;
// pointers to the current request and a session
Cur cur;
// temporary one request object
// current request
Request req;
// users sessions
SessionManager session_manager;
// database
Db db;
DbConn db_conn;
/*
model
*/
// ...
System system;
// functions (ls, cat, emacs, ...)
Functions functions;
// false at the beginning
// !! IMPROVE ME moze to do loggera dac?
bool stdout_is_closed;
/*
view
*/
Templates templates;
private:
enum Header
{
h_200,
h_404,
h_403
};
PostParser post_parser;
PostMultiParser post_multi_parser;
CookieParser cookie_parser;
AcceptEncodingParser accept_encoding_parser;
Compress compress;
FCGX_Request fcgi_request;
int fcgi_socket;
Synchro synchro;
pthread_t signal_thread;
std::string url_to_fetch_on_exit;
std::string send_data_buf;
PT::SpaceToJSON json_generic_serializer;
TextStream<std::wstring> json_out_stream;
std::string aheader_name, aheader_value;
std::wstring html_filtered;
std::string output_8bit;
BinaryPage compressed_output;
bool CheckAccessFromPlugins();
void ProcessRequestThrow();
void ProcessRequest();
void BaseUrlRedirect(int code, bool add_subdomain);
bool BaseUrlRedirect();
void CheckIfNeedSSLredirect();
void SetLocale();
void CheckPostRedirect();
void MakePage();
void Make();
void SaveSessionsIfNeeded(); // !! IMPROVE ME wywalic do menagera sesji??
void LogAccess();
void SendData(const BinaryPage & page, FCGX_Stream * out);
void CreateJSONAnswer();
void ReadRequest();
void SendTextAnswer();
void SendBinaryAnswer();
void SendAnswer();
void LogEnvironmentVariables();
void SetEnv(const char * & env, const char * name);
void ReadEnvVariables();
void ReadGetPostVars();
void CheckIE();
void CheckKonqueror();
void CheckRequestMethod();
void CheckSSL();
void SetSubdomain();
Header GetHTTPStatusCode();
void PrepareSessionCookie();
void FilterContent();
void SendHeaders();
void SendCookies();
bool AddHeader(const wchar_t * name, const wchar_t * value);
bool AddHeader(const std::wstring & name, const std::wstring & value);
bool AddHeader(const wchar_t * name, const PT::WTextStream & value);
bool AddHeader(const std::wstring & name, const PT::WTextStream & value);
bool PrepareHeadersStaticCreateResource(PT::WTextStream & out_path);
void PrepareHeadersStatic();
void PrepareHeaderContentType();
void PrepareHeadersForbidden();
void PrepareHeadersRedirect();
void PrepareHeadersSendFile();
void PrepareHeadersCompression(int compress_encoding);
void PrepareHeadersNormal(Header header, size_t output_size);
void PrepareHeaders(bool compressing, int compress_encoding, Header header, size_t output_size);
int SelectDeflateVersion();
void SelectCompression(size_t source_len, bool & compression_allowed, int & compression_encoding);
bool CanSendContent();
void ClearAfterRequest();
void LogUser(const char * msg, uid_t id);
void LogGroup(const char * msg, gid_t id, bool put_logend = true);
void LogUsers();
void LogEffectiveGroups(std::vector<gid_t> & tab);
void LogGroups();
bool DropPrivileges(const std::string & user, uid_t uid, gid_t gid, bool additional_groups);
static void * SpecialThreadForSignals(void*);
void FetchPageOnExit();
void CreateStaticTree();
// !! IMPROVE ME
// !! move to the session manager?
time_t last_sessions_save;
};
} // namespace Winix
#endif

271
core/basethread.cpp Executable file
View File

@@ -0,0 +1,271 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2010-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <errno.h>
#include "basethread.h"
namespace Winix
{
BaseThread::BaseThread() : thread_signal(PTHREAD_COND_INITIALIZER)
{
synchro = 0;
thread_id = 0;
work_mode = 0;
wake_up_was_called = false;
}
void BaseThread::SetSynchro(Synchro * psynchro)
{
synchro = psynchro;
}
void BaseThread::Mode(int mode)
{
work_mode = mode;
}
pthread_t BaseThread::ThreadId()
{
return thread_id;
}
bool BaseThread::Lock()
{
return synchro->Lock();
}
void BaseThread::Unlock()
{
synchro->Unlock();
}
bool BaseThread::IsExitSignal()
{
bool res = true;
if( Lock() )
{
res = synchro->was_stop_signal;
Unlock();
}
return res;
}
bool BaseThread::BaseInit()
{
bool init_status = false;
if( Lock() )
{
init_status = Init(); // your virtual method
Unlock();
}
return init_status;
}
void BaseThread::BaseUninit()
{
if( Lock() )
{
Uninit(); // your virtual method
Unlock();
}
}
bool BaseThread::BaseSignalReceived()
{
bool make_do = false;
wake_up_was_called = false;
try
{
make_do = SignalReceived(); // your short-time virtual method (objects are locked)
}
catch(...)
{
}
return make_do;
}
// this is called only if your SignalReceived() returned true
void BaseThread::BaseDo()
{
try
{
Do(); // your long-time virtual method (objects are *not* locked)
}
catch(...)
{
}
}
// use it with Lock and Unlock
bool BaseThread::WaitForSignal()
{
if( synchro->was_stop_signal || wake_up_was_called )
return true;
return pthread_cond_wait(&thread_signal, &synchro->mutex) == 0;
}
// you should use this method with: synchro->Lock() and Unlock()
void BaseThread::WakeUpThread()
{
wake_up_was_called = true;
pthread_cond_signal(&thread_signal);
}
// use it with Lock and Unlock
// it breaks only if there was a stop signal or the time has expired
bool BaseThread::WaitForSignalSleep(time_t second)
{
timespec t;
int res;
if( synchro->was_stop_signal )
return true;
t.tv_sec = time(0) + second;
t.tv_nsec = 0;
do
{
res = pthread_cond_timedwait(&thread_signal, &synchro->mutex, &t);
}
while( res == 0 && !synchro->was_stop_signal );
// above condition means there was a signal
// but it was not a stop signal so we should still wait
return res == 0 || res == ETIMEDOUT;
}
void BaseThread::WaitForThread()
{
pthread_join(thread_id, 0);
}
void BaseThread::SignalLoop()
{
bool make_do;
do
{
if( Lock() )
{
make_do = false;
if( WaitForSignal() ) // automatically unlock, wait and lock again when signal comes
if( !synchro->was_stop_signal )
make_do = BaseSignalReceived(); // your short-time virtual method will be called (objects locked)
Unlock(); // unlocking from WaitForSignal()
if( make_do )
BaseDo(); // your long-time virtual method will be called (objects *not* locked)
}
}
while( !IsExitSignal() );
}
void * BaseThread::StartRoutine(void * this_object)
{
BaseThread * base = reinterpret_cast<BaseThread*>(this_object);
if( base->synchro )
{
if( base->BaseInit() )
{
if( base->work_mode == 0 )
base->SignalLoop();
else
base->Work();
base->BaseUninit();
}
}
pthread_exit(0);
return 0;
}
bool BaseThread::StartThread()
{
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
int res = pthread_create(&thread_id, &attr, StartRoutine, this);
pthread_attr_destroy(&attr);
return res == 0;
}
} // namespace Winix

158
core/basethread.h Executable file
View File

@@ -0,0 +1,158 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2010-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_basethread
#define headerfile_winix_core_basethread
#include <pthread.h>
#include "synchro.h"
namespace Winix
{
class BaseThread
{
public:
BaseThread();
// synchro object (must be set)
void SetSynchro(Synchro * psynchro);
// work mode
// we have two modes:
// 0 - there is a loop with SignalReceived() and Do()
// if SignalReceived() returns true then Do() is called
// 1 - only Work() method is called
// the thread exits after Work() has finished
// default: 0
void Mode(int mode);
// starting the second thread
bool StartThread();
// virtual methods which should/can be inherited by your class
// the methods will be called from the other thread
// wake up the second thread
// (if it waits for the signal)
// you should use it with: synchro->Lock() and Unlock()
// if the thread doesn't wait on a signal then nothing is done
virtual void WakeUpThread();
// waiting until the thread exits
// you should call WakeUpThread() before
virtual void WaitForThread();
// initialize the thread
// (global objects are locked)
// if it returns false then the thread immediately exits
// default: true
virtual bool Init() { return true; }
// uninitialize the thread
// this is called before the thread is prepare to detach
// (global objects are locked)
// it's called only if Init() returned true
virtual void Uninit() {}
// returns the thread id
// this identifier is set by StartThread() metdhod
pthread_t ThreadId();
protected:
// signal came (work mode = 0 - default)
// signal comes when an other thread calls WakeUpThread() method
// check specific job and return true to call Do() next
// (global objects are locked -- copy some global objects to local variables)
virtual bool SignalReceived() { return false; };
// if SignalReceived() returned true then this method is called
// global objects are *not* locked -- use only your local variables
// if you have to do something on global objects use synchro->Lock() and synchro->Unlock()
virtual void Do() {}
// this method is called after Init() when Mode(1) is used
// this is for long-time job
// this method is called only once
// global objects are *not* locked
virtual void Work() {}
protected:
Synchro * synchro;
pthread_t thread_id; // thread id - set by StartThread()
pthread_cond_t thread_signal;
int work_mode;
bool wake_up_was_called;
void SignalLoop();
static void * StartRoutine(void *);
bool BaseInit();
void BaseUninit();
bool BaseSignalReceived();
void BaseDo();
bool WaitForSignal();
bool WaitForSignalSleep(time_t second);
bool Lock();
void Unlock();
// if the work done by Do() is long time consuming you should periodically check
// wheter there was a signal for exiting, and if it was just simply return from Do()
// (it's checking with locking and unlocking)
bool IsExitSignal();
};
} // namespace Winix
#endif

626
core/bbcodeparser.cpp Executable file
View File

@@ -0,0 +1,626 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "bbcodeparser.h"
namespace Winix
{
bool BBCODEParser::Equal(const wchar_t * str1, const wchar_t * str2)
{
while( *str1 == *str2 && *str1 != 0 )
{
str1 += 1;
str2 += 1;
}
return *str1 == *str2;
}
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 wchar_t * str, const wchar_t * 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) += L"<br>\n";
}
}
else
{
PrintEscape(*str);
++str;
}
}
}
void BBCODEParser::ReadNormalTextSkipWhite(const wchar_t * & start, const wchar_t * & 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(L"*", pstack[stack_len-1].name) &&
IsNameEqual(L"*", 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 wchar_t * tag)
{
static Tags tags[] = {
{L"*", L"li", L">", false},
{L"b", L"em", L">", true},
{L"i", L"span", L" class=\"bbitalic\">", true},
{L"u", L"span", L" class=\"bbunderline\">", true},
{L"s", L"span", L" class=\"bbstrike\">", true},
{L"code", L"code", L" class=\"bbcode\">", false},
{L"list", L"ul", L" class=\"bblist\">", false},
{L"color", L"span", L" class=\"bbcol%1\">", true},
{L"url", L"a", L" href=\"%u1\">", true},
{L"img", L"img", L" alt=\"%1\" src=\"%u2\">", true},
{L"quote", L"div", L" 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( Equal(tag, tags[i].bbcode) )
return &tags[i];
}
return 0;
}
const BBCODEParser::Tags * BBCODEParser::FindTag(const std::wstring & tag)
{
return FindTag(tag.c_str());
}
void BBCODEParser::PrintArgumentCheckQuotes(const wchar_t * & start, const wchar_t * & 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) += L"&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
{
wchar_t buffer[20];
swprintf(buffer, 20, L"%02X", c);
(*out_string) += '%';
(*out_string) += buffer;
}
}
void BBCODEParser::PrintEscape(int c, bool change_quote)
{
if( c == '<' )
{
(*out_string) += L"&lt;";
}
else
if( c == '>' )
{
(*out_string) += L"&gt;";
}
else
if( c == '&' )
{
(*out_string) += L"&amp;";
}
else
if( c == '\"' && change_quote )
{
(*out_string) += L"&quot;";
}
else
{
(*out_string) += c;
}
}
void BBCODEParser::PrintArgumentEncode(const wchar_t * start, const wchar_t * end)
{
PrintArgumentCheckQuotes(start, end);
TrimWhiteWithNewLines(start, end);
for( ; start<end ; ++start )
PrintEncode(*start);
}
void BBCODEParser::PrintArgumentEscape(const wchar_t * start, const wchar_t * end)
{
PrintArgumentCheckQuotes(start, end);
for( ; start<end ; ++start )
PrintEscape(*start, true); // quotes are escaped as well here
}
void BBCODEParser::CheckOpeningTag(const Tags * tag, const wchar_t * tag_name, bool & condition)
{
if( Equal(tag->html_tag, tag_name) )
{
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, L"li", has_open_li_tag);
CheckOpeningTag(tag, L"ul", has_open_ul_tag);
CheckOpeningTag(tag, L"ol", has_open_ol_tag);
if( has_open_li_tag && !has_list_tag )
{
(*out_string) += L"<ul>\n";
has_open_ul_tag = true;
}
}
void BBCODEParser::PrintEscape(const wchar_t * start, const wchar_t * end, bool change_quote)
{
for( ; start < end ; ++start)
PrintEscape(*start, change_quote);
}
void BBCODEParser::PrintEncode(const wchar_t * start, const wchar_t * end)
{
for( ; start < end ; ++start)
PrintEncode(*start);
}
void BBCODEParser::PutOpeningTagFromEzc()
{
// this can be a tag from Ezc templates system
(*out_string) += '[';
(*out_string) += LastItem().name;
const wchar_t * start = pchar;
while( *pchar && *pchar!=']' )
++pchar;
if( *pchar == ']' )
++pchar;
Put(start, pchar);
}
void BBCODEParser::PutHtmlArgument1(const wchar_t * arg_start, const wchar_t * arg_end, bool has_u)
{
if( has_u )
PrintArgumentEncode(arg_start, arg_end);
else
PrintArgumentEscape(arg_start, arg_end);
}
void BBCODEParser::TrimWhiteWithNewLines(const wchar_t * & start, const wchar_t * & 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 wchar_t * start = pchar;
const wchar_t * 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 wchar_t * arg_start, const wchar_t * arg_end)
{
const wchar_t * 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)
{
CheckOpeningTag(tag);
PutOpeningTagMark();
Put(tag->html_tag);
const wchar_t * start = pchar;
while( *pchar && *pchar != ']' )
++pchar;
PutHtmlArgument(tag, start, pchar);
if( *pchar == ']' )
++pchar;
if( !tag->inline_tag )
{
Put(10);
SkipWhiteLines();
}
}
bool BBCODEParser::PutOpeningTag()
{
const Tags * tag = FindTag(LastItem().name);
if( !tag )
PutOpeningTagFromEzc();
else
PutOpeningTagFromBBCode(tag);
return false;
}
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) += L"\n";
SkipWhiteLines();
}
if( Equal(tag->html_tag, L"li") )
has_open_li_tag = false;
if( Equal(tag->html_tag, L"ol") )
has_open_ol_tag = false;
if( Equal(tag->html_tag, L"ul") )
has_open_ul_tag = false;
}
void BBCODEParser::PutClosingTag(const wchar_t * 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::Uninit()
{
if( has_open_li_tag )
(*out_string) += L"</li>\n";
if( has_open_ol_tag )
(*out_string) += L"</ol>\n";
if( has_open_ul_tag )
(*out_string) += L"</ul>\n";
}
} // namespace Winix

125
core/bbcodeparser.h Executable file
View File

@@ -0,0 +1,125 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_bbcodeparser
#define headerfile_winix_core_bbcodeparser
#include "htmlfilter.h"
namespace Winix
{
class BBCODEParser : public HTMLFilter
{
struct Tags
{
const wchar_t * bbcode;
const wchar_t * html_tag;
const wchar_t * html_argument; // with closing '>'
bool inline_tag;
};
/*
virtual methods
(from HTMLFilter class)
*/
virtual void Init();
virtual void Uninit();
virtual bool IsOpeningTagMark();
virtual bool IsOpeningCommentaryTagMark();
virtual bool IsClosingTagMark();
virtual bool IsClosingXmlSimpleTagMark();
virtual bool IsValidCharForName(int c);
virtual void CheckExceptions();
virtual bool SkipCommentaryTagIfExists();
virtual bool PutOpeningTag();
virtual void PutClosingTag(const wchar_t * tag);
virtual void PutNormalText(const wchar_t * str, const wchar_t * end);
virtual void ReadNormalTextSkipWhite(const wchar_t * & start, const wchar_t * & last_non_white);
/*
others
*/
bool Equal(const wchar_t * str1, const wchar_t * str2);
void PutHtmlArgument1(const wchar_t * arg_start, const wchar_t * arg_end, bool has_u);
void PutHtmlArgument2(const Tags * tag, bool has_u);
void PutHtmlArgument(const Tags * tag, const wchar_t * arg_start, const wchar_t * arg_end);
void PutOpeningTagFromEzc();
void PutOpeningTagFromBBCode(const Tags * tag);
const Tags * FindTag(const wchar_t * tag);
const Tags * FindTag(const std::wstring & tag);
void PrintArgumentCheckQuotes(const wchar_t * & start, const wchar_t * & end);
void PrintEscape(int c, bool change_quote = false);
void PrintEncode(int c);
void PrintEscape(const wchar_t * start, const wchar_t * end, bool change_quote = false);
void PrintEncode(const wchar_t * start, const wchar_t * end);
void PrintArgumentEncode(const wchar_t * start, const wchar_t * end);
void PrintArgumentEscape(const wchar_t * start, const wchar_t * end);
void PutClosingTag(const Tags * tag);
void CheckOpeningTag(const Tags * tag, const wchar_t * tag_name, bool & condition);
void CheckOpeningTag(const Tags * tag);
void TrimWhiteWithNewLines(const wchar_t * & start, const wchar_t * & 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
};
} // namespace Winix
#endif

433
core/compress.cpp Executable file
View File

@@ -0,0 +1,433 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "compress.h"
#include "log.h"
namespace Winix
{
Compress::Compress()
{
buffer_in = 0;
buffer_out = 0;
buffer_max_len = 65536; // 64KB
ready_for_compress = false;
compress_level = 6;
raw_deflate_inited = false;
deflate_inited = false;
gzip_inited = false;
}
Compress::~Compress()
{
delete [] buffer_in;
delete [] buffer_out;
if( raw_deflate_inited )
deflateEnd(&strm_raw_deflate);
if( deflate_inited )
deflateEnd(&strm_deflate);
if( gzip_inited )
deflateEnd(&strm_gzip);
}
bool Compress::AllocateMemory()
{
if( buffer_in )
delete [] buffer_in;
if( buffer_out )
delete [] buffer_out;
buffer_in = 0;
buffer_out = 0;
try
{
buffer_in = new char[buffer_max_len];
buffer_out = new char[buffer_max_len];
}
catch(const std::bad_alloc &)
{
log << log1 << "Compress: can't allocate memory" << logend;
return false;
}
return true;
}
bool Compress::InitRawDeflate()
{
raw_deflate_inited = false;
strm_raw_deflate.next_in = 0;
strm_raw_deflate.zalloc = Z_NULL;
strm_raw_deflate.zfree = Z_NULL;
strm_raw_deflate.opaque = Z_NULL;
int ret = deflateInit2(&strm_raw_deflate, compress_level, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
if( ret != Z_OK )
log << log1 << "Compress: problem with deflateInit2() for raw deflate" << logend;
else
raw_deflate_inited = true;
return ret == Z_OK;
}
bool Compress::InitDeflate()
{
deflate_inited = false;
strm_deflate.next_in = 0;
strm_deflate.zalloc = Z_NULL;
strm_deflate.zfree = Z_NULL;
strm_deflate.opaque = Z_NULL;
int ret = deflateInit2(&strm_deflate, compress_level, Z_DEFLATED, 15, 8, Z_DEFAULT_STRATEGY);
if( ret != Z_OK )
log << log1 << "Compress: problem with deflateInit2() for deflate" << logend;
else
deflate_inited = true;
return ret == Z_OK;
}
bool Compress::InitGzip()
{
gzip_inited = false;
strm_gzip.next_in = 0;
strm_gzip.zalloc = Z_NULL;
strm_gzip.zfree = Z_NULL;
strm_gzip.opaque = Z_NULL;
int ret = deflateInit2(&strm_gzip, compress_level, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY);
if( ret != Z_OK )
log << log1 << "Compress: problem with deflateInit2() for gzip" << logend;
else
gzip_inited = true;
return ret == Z_OK;
}
/*
return:
0 - ok
1 - can't allocate memory
100 - unknown error
*/
int Compress::Init(int compress_level_)
{
compress_level = compress_level_;
if( !AllocateMemory() )
return 1;
if( InitRawDeflate() && InitDeflate() && InitGzip() )
ready_for_compress = true;
else
return 100;
return 0;
}
int Compress::MakeCompress(z_stream & strm, const char * source, size_t source_len, BinaryPage & out_stream, int encoding)
{
int ret, flush;
size_t have;
do
{
strm.avail_in = (source_len > buffer_max_len) ? buffer_max_len : source_len;
source_len -= strm.avail_in;
flush = (source_len == 0) ? Z_FINISH : Z_NO_FLUSH;
strm.next_in = (Bytef*)source;
source += strm.avail_in;
do
{
strm.avail_out = buffer_max_len;
strm.next_out = (Bytef*)buffer_out;
ret = deflate(&strm, flush);
if( ret == Z_STREAM_ERROR || ret == Z_BUF_ERROR )
{
log << log1 << "Compress: problem with deflate()" << logend;
return 2;
}
have = buffer_max_len - strm.avail_out;
last_out_size += have;
out_stream.write(buffer_out, have);
}
while( strm.avail_out == 0 );
if( strm.avail_in != 0 )
{
log << log1 << "Compress: problem with deflate() - not all input is used" << logend;
return 2;
}
}
while( flush != Z_FINISH );
if( ret != Z_STREAM_END )
{
log << log1 << "Compress: problem with deflate() - stream not complete" << logend;
return 2;
}
return 0;
}
void Compress::CopyToInputBuffer(BinaryPage::const_iterator & i, size_t len)
{
for(size_t a=0 ; a<len ; ++a, ++i)
buffer_in[a] = *i;
}
// new way
int Compress::MakeCompress(z_stream & strm, const BinaryPage & page, BinaryPage & out, int encoding)
{
int ret, flush;
size_t have;
BinaryPage::const_iterator i = page.begin();
size_t source_len = page.size();
do
{
strm.avail_in = (source_len > buffer_max_len) ? buffer_max_len : source_len;
source_len -= strm.avail_in;
flush = (source_len == 0) ? Z_FINISH : Z_NO_FLUSH;
strm.next_in = (Bytef*)buffer_in;
CopyToInputBuffer(i, strm.avail_in);
do
{
strm.avail_out = buffer_max_len;
strm.next_out = (Bytef*)buffer_out;
ret = deflate(&strm, flush);
if( ret == Z_STREAM_ERROR || ret == Z_BUF_ERROR )
{
log << log1 << "Compress: problem with deflate()" << logend;
return 2;
}
have = buffer_max_len - strm.avail_out;
last_out_size += have;
out.write(buffer_out, have);
}
while( strm.avail_out == 0 );
if( strm.avail_in != 0 )
{
log << log1 << "Compress: problem with deflate() - not all input is used" << logend;
return 2;
}
}
while( flush != Z_FINISH );
if( ret != Z_STREAM_END )
{
log << log1 << "Compress: problem with deflate() - stream not complete" << logend;
return 2;
}
return 0;
}
z_stream * Compress::SelectStream(int encoding)
{
z_stream * pstrm;
if( encoding == 0 )
pstrm = &strm_raw_deflate;
else
if( encoding == 1 )
pstrm = &strm_deflate;
else
pstrm = &strm_gzip;
return pstrm;
}
void Compress::ResetStream(z_stream * pstrm, int encoding)
{
if( deflateReset(pstrm) != Z_OK )
{
log << log1 << "Compress: problem with deflateReset()" << logend;
deflateEnd(pstrm);
if( encoding == 0 )
InitRawDeflate();
else
if( encoding == 1 )
InitDeflate();
else
InitGzip();
}
}
void Compress::PutLog(size_t source_len, int encoding)
{
double ratio = 100.0 - (double(last_out_size) / double(source_len) * 100.0);
char buffer[30];
sprintf(buffer, "%.1f", ratio);
log << log2 << "Compress: ";
if( encoding == 0 )
log << "raw deflate";
else
if( encoding == 1 )
log << "deflate";
else
log << "gzip";
log << ", original size: " << source_len << ", size after compressing: "
<< (int)last_out_size << ", ratio: " << buffer << "%" << logend;
}
/*
return:
0 - ok;
1 - can't allocate memory
2 - error during compressing
3 - not inited (use Init() first)
100 - unknown
*/
int Compress::Compressing(const char * source, size_t source_len, BinaryPage & out_stream, int encoding)
{
int ret;
z_stream * pstrm;
last_out_size = 0;
out_stream.clear();
if( !ready_for_compress )
{
log << log1 << "Compress: not ready yet" << logend;
return 3;
}
// !! CHECK ME
// it is correct to immediately return? what about headers in the compressed page?
if( source_len == 0 )
return 0;
pstrm = SelectStream(encoding);
ret = MakeCompress(*pstrm, source, source_len, out_stream, encoding);
ResetStream(pstrm, encoding);
PutLog(source_len, encoding);
return ret;
}
/*
return:
0 - ok;
1 - can't allocate memory
2 - error during compressing
3 - not inited (use Init() first)
100 - unknown
*/
int Compress::Compressing(const BinaryPage & in, BinaryPage & out, int encoding)
{
int ret;
z_stream * pstrm;
last_out_size = 0;
out.clear();
if( !ready_for_compress )
{
log << log1 << "Compress: not ready yet" << logend;
return 3;
}
// !! CHECK ME
// it is correct to immediately return? what about headers in the compressed page?
if( in.empty() )
return 0;
pstrm = SelectStream(encoding);
ret = MakeCompress(*pstrm, in, out, encoding);
ResetStream(pstrm, encoding);
PutLog(in.size(), encoding);
return ret;
}
} // namespace Winix

101
core/compress.h Executable file
View File

@@ -0,0 +1,101 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_compress
#define headerfile_winix_core_compress
#include <cstring>
#include <zlib.h>
#include "requesttypes.h"
namespace Winix
{
class Compress
{
public:
Compress();
~Compress();
int Init(int compress_level_ = 6);
/*
encoding:
0 - raw deflate data with no zlib header or trailer, and will not compute an adler32 check value
(for Internet Explorer)
1 - deflate
2 - gzip
*/
int Compressing(const char * source, size_t source_len, BinaryPage & out_stream, int encoding = 2);
int Compressing(const BinaryPage & in, BinaryPage & out, int encoding = 2);
private:
bool AllocateMemory();
bool InitRawDeflate();
bool InitDeflate();
bool InitGzip();
int MakeCompress(z_stream & strm, const char * source, size_t source_len, BinaryPage & out_stream, int encoding);
int MakeCompress(z_stream & strm, const BinaryPage & page, BinaryPage & out, int encoding);
z_stream * SelectStream(int encoding);
void ResetStream(z_stream * pstrm, int encoding);
void PutLog(size_t source_len, int encoding);
void CopyToInputBuffer(BinaryPage::const_iterator & i, size_t len);
int compress_level;
size_t buffer_max_len;
// size of the last compressed page
size_t last_out_size;
char * buffer_in;
char * buffer_out;
z_stream strm_raw_deflate, strm_deflate, strm_gzip;
bool raw_deflate_inited, deflate_inited, gzip_inited;
bool ready_for_compress;
};
} // namespace Winix
#endif

View File

@@ -1,20 +1,51 @@
/* /*
* This file is a part of CMSLU -- Content Management System like Unix * This file is a part of Winix
* and is not publicly distributed * and is distributed under the 2-Clause BSD licence.
* * Author: Tomasz Sowa <t.sowa@ttmath.org>
* Copyright (c) 2008, Tomasz Sowa */
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/ */
#include "config.h" #include "config.h"
#include "log.h"
#include "plugin.h"
#include "misc.h"
#include "crypt.h"
namespace Winix
{
Config::Config() Config::Config()
{ {
default_int = 0;
default_bool = false;
errors_to_stdout = true; errors_to_stdout = true;
} }
@@ -27,24 +58,28 @@ Config::Config()
void Config::ShowError() void Config::ShowError()
{ {
switch( conf_parser.status ) switch( parser.status )
{ {
case ConfParser::ok: case PT::SpaceParser::no_space:
log << log2 << "Config: space not set" << logend;
break;
case PT::SpaceParser::ok:
log << log2 << "Config: syntax ok" << logend; log << log2 << "Config: syntax ok" << logend;
break; break;
case ConfParser::cant_open_file: case PT::SpaceParser::cant_open_file:
if( errors_to_stdout ) 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; break;
case ConfParser::syntax_error: case PT::SpaceParser::syntax_error:
if( errors_to_stdout ) 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; break;
} }
} }
@@ -54,11 +89,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_; 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; log << log2 << "Config: name of the config file is empty" << logend;
return false; return false;
@@ -66,14 +101,16 @@ bool Config::ReadConfig(bool errors_to_stdout_)
log << log2 << "Config: reading a config file" << logend; log << log2 << "Config: reading a config file" << logend;
ConfParser::Status status = conf_parser.Parse( data.config_file.c_str() ); parser.SplitSingle(true);
parser.UTF8(true); // config is always read in UTF-8
parser.SetSpace(space);
PT::SpaceParser::Status status = parser.Parse(config_file);
if( status == ConfParser::ok ) if( status == PT::SpaceParser::ok )
{ {
AssignValues(); AssignValues(stdout_is_closed);
SetAdditionalVariables();
data.SetAdditionalVariables();
return true; return true;
} }
else else
@@ -85,114 +122,387 @@ bool Config::ReadConfig(bool errors_to_stdout_)
void Config::AssignValues()
void Config::AssignValues(bool stdout_is_closed)
{ {
data.log_file = Text("log_file"); demonize = Bool(L"demonize", true);
data.fcgi_socket = Text("fcgi_socket");
data.fcgi_socket_chmod = Int("fcgi_socket_chmod"); user = AText(L"user");
data.fcgi_socket_user = Text("fcgi_socket_user"); group = AText(L"group");
data.fcgi_socket_group = Text("fcgi_socket_group"); additional_groups = Bool(L"additional_groups", true);
data.log_level = Int("log_level");
log_file = AText(L"log_file");
log_notify_file = AText(L"log_notify_file");
log_delimiter = Text(L"log_delimiter", L"---------------------------------------------------------------------------------");
fcgi_socket = AText(L"fcgi_socket");
fcgi_socket_chmod = Int(L"fcgi_socket_chmod", 0770);
fcgi_socket_user = AText(L"fcgi_socket_user");
fcgi_socket_group = AText(L"fcgi_socket_group");
log_level = Int(L"log_level", 1);
log_request = Int(L"log_request", 1);
log_save_each_line = Bool(L"log_save_each_line", false);
log_time_zone_id = Size(L"log_time_zone_id", 34);
log_server_answer = Bool(L"log_server_answer", false);
log_stdout = Bool(L"log_stdout", false);
log_db_query = Bool(L"log_db_query", false);
log_plugin_call = Bool(L"log_plugin_call", false);
log_post_value_size = Size(L"log_post_value_size", 80);
log_env_variables = Bool(L"log_env_variables", false);
log_http_answer_headers = Bool(L"log_http_answer_headers", false);
post_file_max = Size(L"post_file_max", 8388608); // 8 MB
upload_dir = Text(L"upload_dir");
common_dir = Text(L"common_dir");
NoLastSlash(upload_dir);
NoLastSlash(common_dir);
upload_group = AText(L"upload_group");
upload_dirs_chmod = Int(L"upload_dirs_chmod", 0750);
upload_files_chmod = Int(L"upload_files_chmod", 0640);
ListText(L"static_dirs", static_dirs);
dont_use_static_dirs = Bool(L"dont_use_static_dirs", false);
create_thumb = Bool(L"create_thumb", true);
thumb_mode = Int(L"thumb_mode", 2);
thumb_cx = Size(L"thumb_cx", 150);
thumb_cy = Size(L"thumb_cy", 150);
thumb_quality = Int(L"thumb_quality", 92);
image_resize = Bool(L"image_resize", true);
image_mode = Int(L"image_mode", 6);
image_cx = Size(L"image_cx", 1000);
image_cy = Size(L"image_cy", 800);
image_quality = Int(L"image_quality", 92);
convert_cmd = Text(L"convert_cmd", L"/usr/local/bin/convert");
templates_dir = Text(L"templates_dir");
templates_dir_default = Text(L"templates_dir_default");
txt_templates_dir = Text(L"txt_templates_dir");
txt_templates_dir_default = Text(L"txt_templates_dir_default");
templates_fun_prefix = Text(L"templates_fun_prefix", L"fun_");
templates_fun_postfix = Text(L"templates_fun_postfix", L".html");
templates_index = Text(L"templates_index", L"index.html");
template_only_root_use_template_fun = Bool(L"template_only_root_use_template_fun", false);
http_session_id_name = Text(L"http_session_id_name", L"session_id");
db_database = AText(L"db_database");
db_user = AText(L"db_user");
db_pass = AText(L"db_pass");
item_url_empty = Text(L"item_url_empty");
url_proto = Text(L"url_proto", L"http://");
url_ssl_proto = Text(L"url_ssl_proto", L"https://");
use_ssl = Bool(L"use_ssl", false);
use_ssl_static = Bool(L"use_ssl_static", false);
use_ssl_common = Bool(L"use_ssl_common", false);
use_ssl_only_for_logged_users = Bool(L"use_ssl_only_for_logged_users", true);
use_ssl_redirect_code = Int(L"use_ssl_redirect_code", 303);
base_url = Text(L"base_url");
base_url_static = Text(L"base_url_static");
base_url_common = Text(L"base_url_common");
base_url_redirect = Bool(L"base_url_redirect", false);
base_url_redirect_code = Int(L"base_url_redirect_code", 301);
NoLastSlash(base_url);
NoLastSlash(base_url_static);
NoLastSlash(base_url_common);
priv_no_user = Text(L"priv_no_user", L"-- no user --");
priv_no_group = Text(L"priv_no_group", L"-- no group --");
if( !data.stdout_is_closed ) session_max_idle = Int(L"session_max_idle", 10800); // 3h
data.log_stdout = Bool("log_stdout"); session_remember_max_idle = Int(L"session_remember_max_idle", 16070400); // 3 months
session_file = AText(L"session_file");
session_max = Size(L"session_max", 1000000);
compression = Bool(L"compression", true);
compression_page_min_size = Size(L"compression_page_min_size", 512);
compression_encoding = Int(L"compression_encoding", 20);
html_filter = Bool(L"html_filter", true);
html_filter_trim_white = Bool(L"html_filter_trim_white", true);
html_filter_break_word = Int(L"html_filter_break_word", 60);
html_filter_wrap_line = Int(L"html_filter_wrap_line", 110);
html_filter_tabs = Size(L"html_filter_tabs", 2);
html_filter_orphans = Bool(L"html_filter_orphans", true);
html_filter_orphans_mode_str = Text(L"html_filter_orphans_mode_str", L"nbsp");
html_filter_nofilter_tag = Text(L"html_filter_nofilter_tag", L"nofilter");
locale_dir = Text(L"locale_dir");
locale_dir_default = Text(L"locale_dir_default");
locale_max_id = Size(L"locale_max_id", 100);
locale_default_id = Size(L"locale_default_id", 0);
ListText(L"locale_files", locale_files);
title_separator = Text(L"title_separator", L" / ");
http_header_send_file = Text(L"http_header_send_file", L"X-LIGHTTPD-send-file");
editors_html_safe_mode = Bool(L"editors_html_safe_mode", true);
editors_html_safe_mode_skip_root = Bool(L"editors_html_safe_mode_skip_root", true);
plugins_dir = Text(L"plugins_dir", L"/usr/local/winix/plugins");
NoLastSlash(plugins_dir);
ListText(L"plugins", plugin_file);
utf8 = Bool(L"utf8", true);
symlinks_follow_max = Size(L"symlinks_follow_max", 20);
ticket_form_prefix = Text(L"ticket_form_prefix", L"ticketparam");
pass_min_size = Size(L"pass_min_size", 5);
pass_type = Int(L"pass_type", 12);
pass_hash_use_salt = Bool(L"pass_hash_use_salt", false);
pass_hash_salt = Text(L"pass_hash_salt");
pass_use_rsa = Bool(L"pass_use_rsa", false);
pass_rsa_private_key = Text(L"pass_rsa_private_key");
opensll_path = Text(L"opensll_path", L"/usr/bin/openssl");
pattern_cacher_when_delete = Size(L"pattern_cacher_when_delete", 130);
pattern_cacher_how_many_delete = Size(L"pattern_cacher_how_many_delete", 30);
content_type_header = Int(L"content_type_header", 0);
umask = Int(L"umask", 0222);
ezc_max_elements = Size(L"ezc_max_elements", 50000);
ezc_max_loop_elements = Size(L"ezc_max_loop_elements", 5000);
ezc_out_streams_size = Size(L"ezc_out_streams_size", 16);
account_need_email_verification = Bool(L"account_need_email_verification", true);
reset_password_code_expiration_time = Long(L"reset_password_code_expiration_time", 86400);
time_zone_default_id = Size(L"time_zone_default_id", 34);
time_zone_max_id = Size(L"time_zone_max_id", 130);
etc_dir = Text(L"etc_dir", L"");
time_zones_file = Text(L"time_zones_file", L"time_zones.conf");
use_ban_list = Bool(L"use_ban_list", true);
ban_list_soft_max_size = Size(L"ban_list_soft_max_size", 50000);
ban_list_max_size = Size(L"ban_list_max_size", 51000);
ban_level_1_delay = Size(L"ban_level_1_delay", 1800);
ban_level_2_delay = Size(L"ban_level_2_delay", 86400);
ban_level_3_delay = Size(L"ban_level_3_delay", 604800);
incorrect_login_min_time_between_get_post = Size(L"incorrect_login_min_time_between_get_post", 2);
incorrect_login_captcha_treshold = Size(L"incorrect_login_captcha_treshold", 3);
incorrect_login_cannot_login_mode = Int(L"incorrect_login_cannot_login_mode", 0);
incorrect_login_cannot_login_treshold = Size(L"incorrect_login_cannot_login_treshold", 20);
incorrect_login_cannot_login_delay = Size(L"incorrect_login_cannot_login_delay", 1800);
pid_file = Text(L"pid_file", L"");
}
void Config::SetAdditionalVariables()
{
if( html_filter_orphans_mode_str == L"160" )
html_filter_orphans_mode = HTMLFilter::orphan_160space;
else else
data.log_stdout = false; html_filter_orphans_mode = HTMLFilter::orphan_nbsp;
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); for(size_t i=0 ; i<static_dirs.size() ; ++i)
NoLastSlash(static_dirs[i]);
data.one_item_is_showed = Bool("one_item_is_showed"); CheckPasswd();
data.priv_no_user = Text("priv_no_user"); if( content_type_header < 0 || content_type_header > 2 )
data.priv_no_group = Text("priv_no_group"); content_type_header = 0;
if( locale_default_id > locale_max_id )
locale_default_id = locale_max_id;
if( locale_files.empty() )
locale_files.push_back(L"en");
upload_group_int = GetGroupId(upload_group);
} }
std::string & Config::Text(const char * name)
void Config::CheckPasswd()
{ {
ConfParser::Table::iterator i = conf_parser.table.find(name); switch(pass_type)
if( i == conf_parser.table.end() )
{ {
log << log2 << "Config: warning: " << name << " is not defined in the config, default will be: \"" << default_str << "\"" << logend; case WINIX_CRYPT_HASH_NONE:
return default_str; case WINIX_CRYPT_HASH_MD4:
case WINIX_CRYPT_HASH_MD5:
case WINIX_CRYPT_HASH_SHA1:
case WINIX_CRYPT_HASH_SHA224:
case WINIX_CRYPT_HASH_SHA256:
case WINIX_CRYPT_HASH_SHA384:
case WINIX_CRYPT_HASH_SHA512:
break;
default:
pass_type = WINIX_CRYPT_HASH_SHA256;
} }
log << log3 << "Config: " << name << "=" << i->second << logend;
return i->second;
} }
int Config::Int(const char * name) std::wstring & Config::Text(const wchar_t * name)
{ {
ConfParser::Table::iterator i = conf_parser.table.find(name); return space.Text(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;
} }
std::wstring & Config::Text(const wchar_t * name, const wchar_t * def)
bool Config::Bool(const char * name)
{ {
ConfParser::Table::iterator i = conf_parser.table.find(name); return space.Text(name, def);
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;
} }
std::wstring & Config::Text(const std::wstring & name, const wchar_t * def)
void Config::NoLastSlash(std::string & s)
{ {
if( s.empty() ) return space.Text(name, def);
return; }
log << log2 << "Config: removing the last slash from: " << s << logend;
std::string & Config::AText(const wchar_t * name)
if( *(--s.end()) == '/' ) {
s.erase(--s.end()); return space.AText(name);
}
std::string & Config::AText(const wchar_t * name, const char * def)
{
return space.AText(name, def);
}
std::string & Config::AText(const std::wstring & name, const char * def)
{
return space.AText(name, def);
}
int Config::Int(const wchar_t * name)
{
return space.Int(name);
}
int Config::Int(const wchar_t * name, int def)
{
return space.Int(name, def);
}
int Config::Int(const std::wstring & name, int def)
{
return space.Int(name, def);
}
long Config::Long(const wchar_t * name)
{
return space.Long(name);
}
long Config::Long(const wchar_t * name, long def)
{
return space.Long(name, def);
}
long Config::Long(const std::wstring & name, long def)
{
return space.Long(name, def);
}
size_t Config::Size(const wchar_t * name)
{
return space.Size(name);
}
size_t Config::Size(const wchar_t * name, size_t def)
{
return space.Size(name, def);
}
size_t Config::Size(const std::wstring & name, size_t def)
{
return space.Size(name, def);
}
bool Config::Bool(const wchar_t * name)
{
return space.Bool(name);
}
bool Config::Bool(const wchar_t * name, bool def)
{
return space.Bool(name, def);
}
bool Config::Bool(const std::wstring & name, bool def)
{
return space.Bool(name, def);
}
bool Config::ListText(const wchar_t * name, std::vector<std::wstring> & list)
{
return space.ListText(name, list);
}
bool Config::ListText(const std::wstring & name, std::vector<std::wstring> & list)
{
return space.ListText(name, list);
}
bool Config::HasValue(const wchar_t * name, const wchar_t * value)
{
return space.HasValue(name, value);
}
bool Config::HasValue(const wchar_t * name, const std::wstring & value)
{
return space.HasValue(name, value);
}
bool Config::HasValue(const std::wstring & name, const wchar_t * value)
{
return space.HasValue(name, value);
}
bool Config::HasValue(const std::wstring & name, const std::wstring & value)
{
return space.HasValue(name, value);
}
void Config::Print(std::wostream & out)
{
space.Serialize(out);
} }
} // namespace Winix

View File

@@ -1,55 +1,721 @@
/* /*
* This file is a part of CMSLU -- Content Management System like Unix * This file is a part of Winix
* and is not publicly distributed * and is distributed under the 2-Clause BSD licence.
* * Author: Tomasz Sowa <t.sowa@ttmath.org>
* Copyright (c) 2008, Tomasz Sowa */
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/ */
#ifndef headerfileconfig #ifndef headerfile_winix_core_config
#define headerfileconfig #define headerfile_winix_core_config
#include "../confparser/confparser.h"
#include "error.h"
#include "data.h"
#include "log.h"
#include <string> #include <string>
#include "space/spaceparser.h"
#include "htmlfilter.h"
namespace Winix
{
class Config class Config
{ {
public: public:
// name of the config file
// this is the parameter passed to winix programm
std::string config_file;
// start as a demon (in the background)
// default: true
bool demonize;
// system user's name to whom winix should drop privileges
// used only if winix is started as the root
std::string user;
// system group's name to which drop privileges
// used only if winix is started as the root
std::string group;
// setting additional effective groups from /etc/group
// by using initgroups()
// used only if winix is started as the root
// default: true
bool additional_groups;
// log file name, log file name for notifications (sending emails, etc)
std::string log_file, log_notify_file;
// the log level (how much info should be inserted to logs)
// 1 - minimum
// 2 - (default)
// 3 - maximum - all logs
int log_level;
// logging to stdout too
// this option is valid only if 'demonize' option is set to 'false'
// default: false
bool log_stdout;
// how many requests should be saved in the same time
// if you have a very busy server you can incrase this value
// default: 1
int log_request;
// whether to save each line of the config (used for debugging purposes)
// default: false
bool log_save_each_line;
// time zone identifier used in log messages
// this affects only the first line of logs (where there is IP address, request method etc)
// see time_zone_default_id below for more info
// default: 34 (Coordinated Universal Time UTC+00:00)
size_t log_time_zone_id;
// put to log what server is sending back to the client (html/json etc)
// default: false
bool log_server_answer;
// logging db queries
// warning: use it only on a developer's server as it logs the hashes of passwords too
// default: false
bool log_db_query;
// logging when a plugin function is called
// default: false
bool log_plugin_call;
// how many characters in values should be logged from POST parameters
// default: 80
// set to 0 to turn it off
size_t log_post_value_size;
// request delimiter in the log file, default "---------"
std::wstring log_delimiter;
// log environment variables (fastcgi environment)
bool log_env_variables;
// log headers (+cookies) which are returned to the client
// this is what winix has generated -- the web server can change or add other headers
// default: false
bool log_http_answer_headers;
// 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::wstring templates_dir;
std::wstring templates_dir_default; // html templates from winix
std::wstring txt_templates_dir;
std::wstring txt_templates_dir_default; // txt (notifications) templates from winix
// prefix and postfix for functions templates
// default:
// prefix: "fun_"
// postfix: ".html"
std::wstring templates_fun_prefix;
std::wstring templates_fun_postfix;
// main html template
// default: index.html
std::wstring templates_index;
// if true then only root can use 'template' winix function
// default: false
bool template_only_root_use_template_fun;
// the database name, user name and a password for the PostgreSQL database
std::string db_database;
std::string db_user;
std::string db_pass;
// the name of the cookie which has the session identifier
std::wstring http_session_id_name;
// string used in a place where is a user (or group) selected
// !! IMPROVE ME should be moved to locales
std::wstring priv_no_user;
std::wstring priv_no_group;
// time in seconds when a user will be automatically logged out (iddle time)
// default: 10800 = 3 hours
int session_max_idle;
// time in seconds when a user will be automatically logged out
// when he has selected the 'remember me' option when logging in
// this time is usually greater than session_max_idle
// default: 16070400 = 3 months
int session_remember_max_idle;
// a file to which winix stores sessions info
// it is used when winix starts (boots) and quits
std::string session_file;
// how many sessions can be (zero turn off this checking)
// default: 1000000 (one milion)
size_t session_max;
// allow the winix output to be compressed
// default: true
bool compression;
// compress only if the output is greater or equal to this value
// default: 512 bytes
size_t compression_page_min_size;
// 1 - use deflate if available (or raw deflate for Internet Explorer) or don't compress
// 2 - use gzip if available or don't compress
// 10 - prefer deflate -- use deflate (or raw deflate for IE) if both deflate and gzip are available
// 20 - prefer gzip -- use gzip if both deflate and gzip are available
// default: 20
int compression_encoding;
// plugins directory
// default: /usr/local/winix/plugins
std::wstring plugins_dir;
// plugins
// you can provide either a relative path (plugins_dir will be used)
// or a full path to a plugin
std::vector<std::wstring> plugin_file;
// should the html code be cleaned by the html filter
bool html_filter;
// should white characters be trimmed
bool html_filter_trim_white;
// when long words should be broken (a space will be inserted)
// default: after 60 non white characters there will be put a space
// set zero to turn off
size_t html_filter_break_word;
// when long lines should be broken (a new line character will be inserted)
// default: 110
// set zero to turn off
size_t html_filter_wrap_line;
// how many spaces will be put at one tree level
// default: 2
size_t html_filter_tabs;
// use checking for 'orphans' for a specicic language
// default: true
bool html_filter_orphans;
// orphans mode
// either: "nbsp" or "160"
// default: "nbsp"
std::wstring html_filter_orphans_mode_str;
HTMLFilter::OrphanMode html_filter_orphans_mode;
// the html nofilter tag
// content betweeng these tags (opening and closing) will not be filtered
// and this tag will not be included in the html output
// default: nofilter
std::wstring html_filter_nofilter_tag;
// the url of a new empty item (if there is not the subject too)
// !! IMPROVE ME should be moved to locale
std::wstring item_url_empty;
// maximum length of a file send by post multipart form
// default: 8388608 - 8MB
// 0 - not used
size_t post_file_max;
// directory for static files
std::wstring upload_dir;
// additional static directories *not* managed by winix
// you can refer to this directories by using 'static' mount point
// e.g.
// let we say in the config you have:
// static_dirs = ("/home/a", "/home/b", "/home/c")
// and in /etc/fstab (in winix) you have such a line:
// "static /my/dir simplefs static(2)"
// above line in /etc/fstab means that when a user enters http://domain.com/my/dir/file.txt
// then "file.txt" will be taken from "/home/c/file.txt"
// this is useful for some javascript files which are protected from running from other domains
std::vector<std::wstring> static_dirs;
// sometimes you can have trouble when you have set an incorrect static path in /etc/fstab
// in such a case set dont_use_static_dirs to true
// and winix will behave as there are not any static directories
// so you can correct your mistake and then set this value to false
bool dont_use_static_dirs;
// static common directory
// this is a place where there are some common javascripts, images, css files
// winix is allowed to read some files from there
// for example ckeditor config, vim config and so on
// winix read it as a ezc template and put it into database
// default: empty
std::wstring common_dir;
// system group's name for new uploaded files (created directories in the file system)
// it can be empty (it is not used then)
std::string upload_group;
// this value will be set based on upload_group
// will be -1 if upload_group is empty or if it is invalid
int upload_group_int;
// chmod of newly created directories (under upload_dir)
// default: 0750
int upload_dirs_chmod;
// chmod of newly created files (under upload_dir)
// default: 0640
int upload_files_chmod;
// create a thumbnail from an image
// default: true
bool create_thumb;
// the mode of creating a thumbnail
// width means thumb_cx, height means thumb_cy
// 1: Width given, height automagically selected to preserve aspect ratio.
// 2: Height given, width automagically selected to preserve aspect ratio.
// 3: Maximum values of height and width given, aspect ratio preserved.
// 4: Minimum values of width and height given, aspect ratio preserved.
// 5: Width and height emphatically given, original aspect ratio ignored.
// 6: Change as per widthxheight (3) but only if an image dimension exceeds a specified dimension.
// 7: Change dimensions only if both image dimensions are less than specified dimensions.
// default: 2
int thumb_mode;
// width of thumbnails
// default: 150
size_t thumb_cx;
// height of thumbnails
// default: 150
size_t thumb_cy;
// quality of thumbnails
// from 0 (the worst) to 100 (the best)
// more info: http://www.imagemagick.org/script/command-line-options.php?ImageMagick=p4jtel7557hovd34ui3tgb54h6#quality
// default: 92
int thumb_quality;
// resizing images
// this not affects thumbnails
// default: true
bool image_resize;
// the mode of resizing an image
// the same as 'thumb_mode' above
// default: 6
int image_mode;
// width of images
// default: 1000
size_t image_cx;
// height of images
// default: 800
size_t image_cy;
// quality of an image (the same as in thumbnails)
// from 0 (the worst) to 100 (the best)
// default: 92
int image_quality;
// the convert program (ImageMagic) (for images and thumbnails)
// default: /usr/local/bin/convert
std::wstring convert_cmd;
// directory with locale files
std::wstring locale_dir;
// directory with default locale files (those from winix)
std::wstring locale_dir_default;
// locale files (e.g. "en", "pl")
// default: only one item: en
std::vector<std::wstring> locale_files;
// a maximum value of a locale identifier
// default: 100 (maximum: 1000)
// each locale files should have its own identifier (in "winix_locale_id" field)
// from zero to this value
size_t locale_max_id;
// locale for not logged users
// or for newly created accounts
// default: 0
size_t locale_default_id;
// url protocol
// default: http://
std::wstring url_proto;
// url protocol when using SSL
// default: https://
std::wstring url_ssl_proto;
// enables SSL
// it means this site should be accessed through SSL encrypted connection
// default: false
bool use_ssl;
// enables SSL for static content
// used mainly in templates, look at doc_base_url_static ezc function
// default: false
bool use_ssl_static;
// enables SSL for common content
// used mainly in templates, look at doc_base_url_common ezc function
// default: false
bool use_ssl_common;
// if SSL is enabled then if this is true the SSL will be used
// only for logged users
// default: true
bool use_ssl_only_for_logged_users;
// if current connection is without SSL and should be made through SSL
// or if is via SSL and should be done in plain text
// then we make a redirect
// default: 303
int use_ssl_redirect_code;
// when the HOST_HTTP environment variable is not equal to '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.
// set this option to false if you have multiple subdomains
// default: false
bool base_url_redirect;
// the HTTP code used during the base redirect
// default: 301
int base_url_redirect_code;
// the main address of the site (e.g. www.someserver.com)
// (without http:// prefix)
std::wstring base_url;
// static content not authorized by winix
// (e.g. static.someserver.com)
std::wstring base_url_static;
// additional static server for common content (not authorized)
// (e.g. common.someserver.com)
std::wstring base_url_common;
// separator used in <title> html tag
std::wstring title_separator;
// http header recognized by www server as a file to send back
// default: X-LIGHTTPD-send-file
std::wstring http_header_send_file;
// in editors (emacs, ckeditor,...) the html will be filtered and unsafe tags
// will be dropped (script, frame, etc.)
// default: true;
bool editors_html_safe_mode;
// don't filter the html code for root
// default: true
// (if true the html code for root is not filtered)
bool editors_html_safe_mode_skip_root;
// charset used in templates, locales, logs etc.
// default: true (UTF-8)
// if false it means 8-bit ASCII
bool utf8;
// how many maximum symlinks can be followed
// (symlinks on directories as well)
// default: 20
size_t symlinks_follow_max;
// the prefix of a name of html form controls used in the ticket plugin
// default: ticketparam
std::wstring ticket_form_prefix;
// the minimal size of a user's password
// default: 5
size_t pass_min_size;
// how passwords should be stored
// 0 - plain text
// 1 - md4 hash
// 2 - md5 hash
// 10 - sha1 hash
// 11 - sha224 hash
// 12 - sha256 hash (default)
// 13 - sha384 hash
// 14 - sha512 hash
int pass_type;
// whether the passwords' hashes should be salted or not
// this affects newly created accounts
// default: false
bool pass_hash_use_salt;
// salt to a password's hash
// default empty
// !! once you set this salt don't change it any more (people wouldn't be allowed to login)
std::wstring pass_hash_salt;
// whether the passwords' hashes should be encrypted
// this affects newly created accounts
// default: false
bool pass_use_rsa;
// path to a RSA private key
// this is actually private + public key in one file
// generated by "openssl genrsa"
// default empty which means encryption will not be used
// !! once you set these keys don't change it any more (people wouldn't be allowed to login)
std::wstring pass_rsa_private_key;
// path to 'openssl'
// default: /usr/bin/openssl
std::wstring opensll_path;
// setting when we should delete patterns (EZC patterns)
// we are deleting when we have more (or equal) patterns than 'when_delete'
// and then we are deleting 'how_many_del' patterns
// those patterns comes from items (pages) with executable bit set
size_t pattern_cacher_when_delete;
size_t pattern_cacher_how_many_delete;
// header "Content-Type" send to the client
// 0 - text/html - for HTML
// 1 - application/xhtml+xml - for XHTML 1.0
// 2 - application/xml - for XHTML 1.0 or for XHTML 1.1
// default: 0
// if utf8 is true then "; charset=UTF-8" will also be appended
int content_type_header;
// global umask
// it is used when an user doesn't have your own umask or for guests (not logged users)
// default: 0222
int umask;
// maximum number for elements through the whole template
// default: 50000
size_t ezc_max_elements;
// maximum number of each [for] loop
// default: 5000 (from ezc generator)
size_t ezc_max_loop_elements;
// how many output streams do we have in Request class
// default: 16 (64 maximum)
size_t ezc_out_streams_size;
// when true then when a user want to create a new account
// he has to provide his email and a message will be sent back to him
// with a link to activate the account
// default: true
bool account_need_email_verification;
// when a user forgot his password we are able to send an email to him
// with a link to the page where there is a html form for setting a new password
// this option tells how long (in seconds) the link is valid
// default: 86400 (24 hours)
long reset_password_code_expiration_time;
// time zone identifier for not logged users
// or for newly created accounts
// those identifiers you can see in etc/time_zones.conf file
// or by using timezone winix function with 'a' parameter (timezone/a) (!!IMPROVE ME NOT IMPLEMENTED YET)
// default: 34 (Coordinated Universal Time UTC+00:00)
size_t time_zone_default_id;
// a maximum value of a time zone identifier
// time zones with an id greater than this will be skipped
// default: 130 (maximum: 1000)
size_t time_zone_max_id;
// a directory in which there are some config files
// used mainly when winix starts
// default: empty (means not for using)
std::wstring etc_dir;
// a file in etc_dir with time zones info
// default: time_zones.conf
// this is a Space structure with all time zones
// with following format:
// "tz_-12:00" ( # the name of a space is also a key to the locale files
// tz_offset_str = "-12:00" # a string representing the offset from UTC in a format: [+|-]HH:MM
// tz_has_dst = "false" # whether the time zone has daylight saving time (bool)
// tz_dst_offset = "" # offset of the daylight saving time
// tz_dst_start = "" # when the daylight saving time starts, format: MM:DD HH:MM:SS
// tz_dst_end = "") # when the daylight saving time ends, format: MM:DD HH:MM:SS
// each time zone is in a seperate space
std::wstring time_zones_file;
// turn on the IP ban mechanizm
// we have got three levels of bans (level 1, level 2, and the highest level 3)
// default: true
bool use_ban_list;
// the so called 'soft' max size
// read below description for explanation
// this is introduced to avoid deleting only one record from the ban list
// default: 50000
size_t ban_list_soft_max_size;
// this is the 'hard' max size of an IP's ban list
// if there are more records than this value
// then some of them will be removed (until the size will be ban_list_soft_max_size equal)
// this value should be a little larger from ban_list_soft_max_size
// default: 51000
size_t ban_list_max_size;
// delay in seconds of the first level ban
// default: 1800 (30 minutes)
// it means withing the next 30 minutes you see only 'you are banned...' message on your webbrowser
size_t ban_level_1_delay;
// delay in seconds of the second level ban
// default: 86400 (24 hours)
size_t ban_level_2_delay;
// delay in seconds of the third level ban
// default: 604800 (7 days)
size_t ban_level_3_delay;
// the minimum time in seconds which has to pass between the first GET request
// (showing your the login form) and the second POST request (which sends the
// login and password to the server)
// if the time is shorter then the login attempt is treated as incorrect
// (the same as if you provide incorrect user/password)
// default: 2
size_t incorrect_login_min_time_between_get_post;
// how many incorrect logins there must have been passed to display a captcha
// next to the login form
// default: 3
size_t incorrect_login_captcha_treshold;
// the way how we prevent to login if there are too many incorrect login attempts
// 0 - 'block logging' - do not show the login form in 'login' winix function
// (instead a warning message will be printed)
// 1 - add to ban list (warning: people from this IP will not be able to see your site and do anything)
// default: 0
int incorrect_login_cannot_login_mode;
// after how many incorrect login attempts we do the incorrect_login_cannot_login_mode action
// default: 20
size_t incorrect_login_cannot_login_treshold;
// used when incorrect_login_cannot_login_mode is zero
// it is the time which should be passed to allow logging
// default: 1800 (30 minutes)
// if incorrect_login_cannot_login_mode is one then ban_level_X_delay times
// will be taken accordingly
size_t incorrect_login_cannot_login_delay;
// pid file (a full path to a pid file)
// default: empty which means there is not a pid file used
// pid file is saved after winix has dropped privileges
std::wstring pid_file;
Config(); Config();
bool ReadConfig(bool errors_to_stdout_); bool ReadConfig(bool errors_to_stdout_, bool stdout_is_closed = true);
std::wstring & Text(const wchar_t * name);
std::wstring & Text(const wchar_t * name, const wchar_t * def);
std::wstring & Text(const std::wstring & name, const wchar_t * def);
std::string & AText(const wchar_t * name);
std::string & AText(const wchar_t * name, const char * def);
std::string & AText(const std::wstring & name, const char * def);
int Int(const wchar_t *);
int Int(const wchar_t * name, int def);
int Int(const std::wstring & name, int def);
long Long(const wchar_t *);
long Long(const wchar_t * name, long def);
long Long(const std::wstring & name, long def);
size_t Size(const wchar_t *);
size_t Size(const wchar_t * name, size_t def);
size_t Size(const std::wstring & name, size_t def);
bool Bool(const wchar_t *);
bool Bool(const wchar_t * name, bool def);
bool Bool(const std::wstring & name, bool def);
bool ListText(const wchar_t * name, std::vector<std::wstring> & list);
bool ListText(const std::wstring & name, std::vector<std::wstring> & list);
bool HasValue(const wchar_t * name, const wchar_t * value);
bool HasValue(const wchar_t * name, const std::wstring & value);
bool HasValue(const std::wstring & name, const wchar_t * value);
bool HasValue(const std::wstring & name, const std::wstring & value);
// for debug
void Print(std::wostream & out);
// raw access to the config
PT::Space space;
private: private:
ConfParser conf_parser;
void ShowError();
void AssignValues();
std::string & Text(const char *);
int Int(const char *);
bool Bool(const char *);
PT::SpaceParser parser;
std::string default_str; std::string default_str;
int default_int;
bool default_bool;
bool errors_to_stdout; bool errors_to_stdout;
void NoLastSlash(std::string & s); void ShowError();
void AssignValues(bool stdout_is_closed);
void SetAdditionalVariables();
void CheckPasswd();
}; };
} // namespace Winix
#endif #endif

View File

@@ -1,27 +1,58 @@
/* /*
* This file is a part of CMSLU -- Content Management System like Unix * This file is a part of Winix
* and is not publicly distributed * and is distributed under the 2-Clause BSD licence.
* * Author: Tomasz Sowa <t.sowa@ttmath.org>
* Copyright (c) 2008, Tomasz Sowa */
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/ */
#ifndef headerfilecookieparser #ifndef headerfile_winix_core_cookieparser
#define headerfilecookieparser #define headerfile_winix_core_cookieparser
#include <fcgiapp.h> #include <fcgiapp.h>
#include "httpsimpleparser.h" #include "httpsimpleparser.h"
#include "requesttypes.h" #include "requesttypes.h"
#include "log.h"
namespace Winix
{
class CookieParser : public HttpSimpleParser class CookieParser : public HttpSimpleParser
{ {
const char * cookie_string; const char * cookie_string;
CookieTable & cookie_table; CookieTab * cookie_tab;
std::wstring temp_name, temp_value;
bool input_as_utf8;
protected: protected:
@@ -35,36 +66,68 @@ protected:
return (int)(unsigned char)*(cookie_string++); return (int)(unsigned char)*(cookie_string++);
} }
void ConvStr(const std::string & src, std::wstring & dst)
{
if( input_as_utf8 )
PT::UTF8ToWide(src, dst);
else
AssignString(src, dst);
}
virtual void Parameter(std::string & name, std::string & value) virtual void Parameter(std::string & name, std::string & value)
{ {
// Cookie names are case insensitive according to section 3.1 of RFC 2965 // Cookie names are case insensitive according to section 3.1 of RFC 2965
// (we don't use locale here)
ToLower(name); ToLower(name);
std::pair<CookieTable::iterator, bool> res = cookie_table.insert( std::make_pair(name, value) ); ConvStr(name, temp_name);
ConvStr(value, temp_value);
log << log2 << "Cookie, name: \"" << name << "\", value: \"" << value << "\""; std::pair<CookieTab::iterator, bool> res = cookie_tab->insert( std::make_pair(temp_name, temp_value) );
log << log2 << "Cookie, name: \"" << temp_name << "\", value: \"" << temp_value << "\"";
if( res.second == false ) if( res.second == false )
log << log2 << " (skipped)"; {
res.first->second = temp_value;
log << " (overwritten)";
}
log << log2 << logend; log << logend;
} }
public: public:
CookieParser(const char * cookie_string_, CookieTable & cookie_table_) : cookie_string(cookie_string_), cookie_table(cookie_table_) CookieParser()
{ {
input_as_utf8 = false;
HttpSimpleParser::separator = ';'; HttpSimpleParser::separator = ';';
HttpSimpleParser::value_can_be_quoted = true; HttpSimpleParser::value_can_be_quoted = true;
HttpSimpleParser::skip_white_chars = true; HttpSimpleParser::skip_white_chars = true;
HttpSimpleParser::recognize_special_chars = false; HttpSimpleParser::recognize_special_chars = false;
} }
void UTF8(bool utf)
{
input_as_utf8 = utf;
}
// cookie_string can be null
void Parse(const char * cookie_string_, CookieTab & cookie_tab_)
{
cookie_string = cookie_string_;
cookie_tab = &cookie_tab_;
HttpSimpleParser::Parse();
}
}; };
} // namespace Winix
#endif #endif

348
core/crypt.cpp Executable file
View File

@@ -0,0 +1,348 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2011-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <cstring>
#include "crypt.h"
#include "utf8/utf8.h"
#include "log.h"
namespace Winix
{
void Crypt::SetConfig(Config * pconfig)
{
config = pconfig;
}
char Crypt::ConvertToHexForm(int val)
{
if( val < 10 )
return val + '0';
return val - 10 + 'a';
}
bool Crypt::HashBin(int hash, const char * in, size_t inlen, std::string & out)
{
out.clear();
if( !config )
return false;
run.Clear();
PT::WideToUTF8(config->opensll_path, command);
run.Cmd(command);
run.Par("dgst");
run.Par("-binary");
switch(hash)
{
case WINIX_CRYPT_HASH_MD4: run.Par("-md4"); break;
case WINIX_CRYPT_HASH_MD5: run.Par("-md5"); break;
case WINIX_CRYPT_HASH_SHA1: run.Par("-sha1"); break;
case WINIX_CRYPT_HASH_SHA224: run.Par("-sha224"); break;
case WINIX_CRYPT_HASH_SHA256: run.Par("-sha256"); break;
case WINIX_CRYPT_HASH_SHA384: run.Par("-sha384"); break;
case WINIX_CRYPT_HASH_SHA512: run.Par("-sha512"); break;
default:
return false;
}
return run.Go(in, inlen, out) == 0;
}
bool Crypt::HashBin(int hash, const char * in, std::string & out)
{
size_t len = strlen(in);
return HashBin(hash, in, len, out);
}
bool Crypt::HashBin(int hash, const std::string & in, std::string & out)
{
return HashBin(hash, in.c_str(), in.size(), out);
}
bool Crypt::HashBin(int hash, const wchar_t * in, size_t inlen, std::string & out)
{
PT::WideToUTF8(in, inlen, bufina);
int res = HashBin(hash, bufina.c_str(), bufina.size(), out);
bufina.clear();
return res;
}
bool Crypt::HashBin(int hash, const wchar_t * in, std::string & out)
{
size_t len = wcslen(in);
return HashBin(hash, in, len, out);
}
bool Crypt::HashBin(int hash, const std::wstring & in, std::string & out)
{
return HashBin(hash, in.c_str(), in.size(), out);
}
bool Crypt::HashHex(int hash, const char * in, size_t inlen, std::string & out)
{
int res = HashBin(hash, in, inlen, out_temp);
ConvertToHexForm(out_temp, out);
out_temp.clear();
return res;
}
bool Crypt::HashHex(int hash, const char * in, std::string & out)
{
size_t len = strlen(in);
return HashHex(hash, in, len, out);
}
bool Crypt::HashHex(int hash, const std::string & in, std::string & out)
{
return HashHex(hash, in.c_str(), in.size(), out);
}
bool Crypt::HashHex(int hash, const wchar_t * in, size_t inlen, std::wstring & out)
{
int res = HashBin(hash, in, inlen, out_temp);
ConvertToHexForm(out_temp, out);
out_temp.clear();
return res;
}
bool Crypt::HashHex(int hash, const wchar_t * in, std::wstring & out)
{
size_t len = wcslen(in);
return HashHex(hash, in, len, out);
}
bool Crypt::HashHex(int hash, const std::wstring & in, std::wstring & out)
{
return HashHex(hash, in.c_str(), in.size(), out);
}
bool IsAllWhite(const char * str)
{
for( ; *str ; ++str)
{
if( !(IsWhite(*str) || *str==10) )
return false;
}
return true;
}
bool Crypt::RSA(bool encrypt, const char * keypath, const char * in, size_t inlen, std::string & out)
{
out.clear();
if( !config || IsAllWhite(keypath) )
return false;
run.Clear();
PT::WideToUTF8(config->opensll_path, command);
run.Cmd(command);
run.Par("rsautl");
run.Par("-inkey");
run.Par(keypath);
if(encrypt)
run.Par("-encrypt");
else
run.Par("-decrypt");
return run.Go(in, inlen, out) == 0;
}
bool Crypt::RSA(bool encrypt, const char * keypath, const std::string & in, std::string & out)
{
return RSA(encrypt, keypath, in.c_str(), in.size(), out);
}
bool Crypt::RSA(bool encrypt, const std::string & keypath, const std::string & in, std::string & out)
{
return RSA(encrypt, keypath.c_str(), in.c_str(), in.size(), out);
}
bool Crypt::RSA(bool encrypt, const wchar_t * keypath, const char * in, size_t inlen, std::string & out)
{
PT::WideToUTF8(keypath, keypatha);
return RSA(encrypt, keypatha.c_str(), in, inlen, out);
}
bool Crypt::RSA(bool encrypt, const wchar_t * keypath, const std::string & in, std::string & out)
{
return RSA(encrypt, keypath, in.c_str(), in.size(), out);
}
bool Crypt::RSA(bool encrypt, const std::wstring & keypath, const std::string & in, std::string & out)
{
return RSA(encrypt, keypath.c_str(), in.c_str(), in.size(), out);
}
bool Crypt::PassHash(const std::wstring & salt, UserPass & up)
{
bool result = true;
up.pass_hash_salted = false;
if( up.pass_type != WINIX_CRYPT_HASH_NONE )
{
pass_org = up.pass;
pass_salted = up.pass;
pass_salted += salt;
if( HashHex(up.pass_type, pass_salted, up.pass) )
{
if( !salt.empty() )
up.pass_hash_salted = true;
}
else
{
log << log1 << "Crypt: problem with generating a hash, the password will not be hashed" << logend;
up.pass = pass_org;
up.pass_type = WINIX_CRYPT_HASH_NONE;
result = false;
}
ClearString(pass_salted);
ClearString(pass_org);
}
return result;
}
bool Crypt::PassCrypt(const std::wstring & path_to_rsa_private_key, UserPass & up)
{
bool result = false;
ClearString(up.pass_encrypted);
if( !path_to_rsa_private_key.empty() )
{
PT::WideToUTF8(up.pass, passa);
if( RSA(true, path_to_rsa_private_key, passa, up.pass_encrypted) )
{
result = true;
}
else
{
ClearString(up.pass_encrypted);
log << log1 << "AddUser: problem with encrypting, the password will not be encrypted!" << logend;
}
ClearString(passa);
}
return result;
}
void Crypt::PassHashCrypt(const std::wstring & salt, const std::wstring & path_to_rsa_private_key, UserPass & up)
{
PassHash(salt, up);
PassCrypt(path_to_rsa_private_key, up);
}
void Crypt::PassHashCrypt(UserPass & up)
{
up.pass_type = config->pass_type;
empty.clear();
if( config->pass_hash_use_salt && !config->pass_hash_salt.empty() )
PassHash(config->pass_hash_salt, up);
else
PassHash(empty, up);
if( config->pass_use_rsa && !config->pass_rsa_private_key.empty() )
PassCrypt(config->pass_rsa_private_key, up);
}
} // namespace Winix

294
core/crypt.h Executable file
View File

@@ -0,0 +1,294 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2011-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_crypt
#define headerfile_winix_core_crypt
#include <string>
#include "run.h"
#include "config.h"
#include "user.h"
namespace Winix
{
/*
the kind of hashes we are able to obtain in winix
*/
#define WINIX_CRYPT_HASH_NONE 0
#define WINIX_CRYPT_HASH_MD4 1
#define WINIX_CRYPT_HASH_MD5 2
#define WINIX_CRYPT_HASH_SHA1 10
#define WINIX_CRYPT_HASH_SHA224 11
#define WINIX_CRYPT_HASH_SHA256 12
#define WINIX_CRYPT_HASH_SHA384 13
#define WINIX_CRYPT_HASH_SHA512 14
/*
calculating hashes, encrypting and decrypting with RSA
*/
class Crypt
{
public:
void SetConfig(Config * pconfig);
/*
calculating a hash from a given input
input:
hash - the kind of the hash - WINIX_CRYPT_HASH_*
in - input buffer
inlen - the length of the buffer
output:
out - the hash in binary form
*/
bool HashBin(int hash, const char * in, size_t inlen, std::string & out);
bool HashBin(int hash, const char * in, std::string & out);
bool HashBin(int hash, const std::string & in, std::string & out);
/*
calculating a hash from a given input
the input string is first changed to UTF8 and then hash is calculated
input:
hash - the kind of the hash - WINIX_CRYPT_HASH_*
in - input buffer
inlen - the length of the buffer
output:
out - the hash in binary form
*/
bool HashBin(int hash, const wchar_t * in, size_t inlen, std::string & out);
bool HashBin(int hash, const wchar_t * in, std::string & out);
bool HashBin(int hash, const std::wstring & in, std::string & out);
/*
calculating a hash from a given input
input:
hash - the kind of the hash - WINIX_CRYPT_HASH_*
in - input buffer
inlen - the length of the buffer
output:
out - the hash in the hex form (one byte is saved as two hex digits)
*/
bool HashHex(int hash, const char * in, size_t inlen, std::string & out);
bool HashHex(int hash, const char * in, std::string & out);
bool HashHex(int hash, const std::string & in, std::string & out);
/*
calculating a hash from a given input
the input string is first changed to UTF8 and then hash is calculated
input:
hash - the kind of the hash - WINIX_CRYPT_HASH_*
in - input buffer
inlen - the length of the buffer
output:
out - the hash in the hex form (one byte is saved as two hex digits)
the 'out' here is std::wstring (not std::string like beforehand)
*/
bool HashHex(int hash, const wchar_t * in, size_t inlen, std::wstring & out);
bool HashHex(int hash, const wchar_t * in, std::wstring & out);
bool HashHex(int hash, const std::wstring & in, std::wstring & out);
/*
encrypt/decrypt by using RSA algorithm
input:
encrypt - true means encrypting, false means decrypting
keypath - path to a RSA private key (this is a private and public key in one file)
in - input buffer
inlen - the size of the buffer
output:
out - encrypted or decrypted buffer (always binary)
*/
bool RSA(bool encrypt, const char * keypath, const char * in, size_t inlen, std::string & out);
bool RSA(bool encrypt, const char * keypath, const std::string & in, std::string & out);
bool RSA(bool encrypt, const std::string & keypath, const std::string & in, std::string & out);
bool RSA(bool encrypt, const wchar_t * keypath, const char * in, size_t inlen, std::string & out);
bool RSA(bool encrypt, const wchar_t * keypath, const std::string & in, std::string & out);
bool RSA(bool encrypt, const std::wstring & keypath, const std::string & in, std::string & out);
/*
this method creates a hash from the given plain text password
input.
salt - salt for the hash
up.pass_type - what kind of hash do you want - look at WINIX_CRYPT_HASH_* macros (in crypt.h)
up.pass - plain text password
if salt is empty then the hash will not be salted
output:
up.pass_type - (can be changed to 0 when there is a problem with generating a hash)
up.pass - hash from the password (or plain text if up.pass_type was zero)
up.pass_hash_salted (true if the hash is salted - when salt was not empty)
if there is a problem with generating a hash the method stores a plain text password
and changes up.pass_type to zero (plain text passwords are not salted)
*/
bool PassHash(const std::wstring & salt, UserPass & up);
/*
this method encrypts the given password
input:
path_to_rsa_private_key - a path to rsa private key (this are a private and public keys both in one file)
up.pass - given password (can be a plain text or a hash)
if path_to_rsa_private_key is empty then the password will not be encrypted
output:
up.pass_encrypted
if there is a problem (or the path to the key is empty) then up.pass_encrypted will be empty
and the method returns false
*/
bool PassCrypt(const std::wstring & path_to_rsa_private_key, UserPass & up);
/*
this method creates a hash from the given plain text password and then encrypts it
input:
salt - salt for the hash
path_to_rsa_private_key - a path to rsa private key (this are a private and public keys both in one file)
up.pass_type - what kind of hash do you want - look at WINIX_CRYPT_HASH_* macros (in crypt.h)
up.pass - plain text password
if salt is empty then the hash will not be salted
if path_to_rsa_private_key is empty then the password will not be encrypted
output:
up.pass_type - (can be changed to 0 when there is a problem with generating a hash)
up.pass - hash from the password (or plain text if up.pass_type was zero)
up.pass_hash_salted (true if the hash is salted - when salt was not empty)
up.pass_encrypted - encrypted password (if not empty)
*/
void PassHashCrypt(const std::wstring & salt, const std::wstring & path_to_rsa_private_key, UserPass & up);
/*
this method creates a hash from the given plain text password and then encrypts it
input:
up.pass - plain text password
output:
up.pass_type - what kind of hash there is in up.pass
up.pass - hash from the password (or plain text if up.pass_type is zero)
up.pass_hash_salted - true if the hash is salted (plain text are never salted)
up.pass_encrypted - encrypted password (if not empty)
*/
void PassHashCrypt(UserPass & up);
/*
putting some characters into the string and then calling clear()
*/
template<class StringType>
void ClearString(StringType & str);
private:
Config * config;
Run run;
std::string command, bufina, keypatha;
//std::wstring pass_salted;//, pass_hashed;
//std::string pass_hasheda, pass_encrypteda;
std::wstring pass_salted, pass_org;
std::string passa, out_temp;
std::wstring empty;
template<typename StringType>
void ConvertToHexForm(const std::string & in, StringType & out);
char ConvertToHexForm(int val);
};
template<typename StringType>
void Crypt::ClearString(StringType & str)
{
for(size_t i=0 ; i<str.size() ; ++i)
str[i] = 0x0c;
str.clear();
}
template<typename StringType>
void Crypt::ConvertToHexForm(const std::string & in, StringType & out)
{
out.clear();
if( in.size() * 2 > out.capacity() )
out.reserve(in.size() * 2);
for(size_t i=0 ; i<in.size() ; ++i)
{
out += ConvertToHexForm(((unsigned char)in[i]) >> 4);
out += ConvertToHexForm(((unsigned char)in[i]) & 0x0f);
}
}
} // namespace Winix
#endif

68
core/cur.h Executable file
View File

@@ -0,0 +1,68 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2010-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_cur
#define headerfile_winix_core_cur
#include "request.h"
#include "session.h"
#include "mount.h"
namespace Winix
{
/*
current request and session
*/
struct Cur
{
Request * request;
Session * session;
Mount * mount;
// those pointers are never null, if there is no a session for the user
// the 'session' pointer pointers at a special temporary session
};
} // namespace Winix
#endif

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, 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( base_url_http_host.empty() )
return;
// removing the last slash (if it is present)
if( base_url_http_host[ base_url_http_host.size() - 1 ] == '/' )
base_url_http_host.erase( base_url_http_host.end() - 1 );
}

View File

@@ -1,132 +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 headerfiledata
#define headerfiledata
#include <string>
#include <vector>
#include <map>
#include <string.h>
#include "misc.h"
#include "item.h"
#include "error.h"
#include "dirs.h"
#include "users.h"
#include "groups.h"
#include "functions.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
std::string log_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;
// 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;
Data();
private:
void SetHttpHost();
};
extern Data data;
#endif

File diff suppressed because it is too large Load Diff

110
core/db.h
View File

@@ -1,110 +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 headerfilecoredb
#define headerfilecoredb
#include <string>
#include <vector>
#include <map>
#include <sstream>
#include <libpq-fe.h>
#include <cstdio>
#include "log.h"
#include "item.h"
#include "misc.h"
#include "error.h"
#include "dircontainer.h"
#include "user.h"
#include "group.h"
#include "ugcontainer.h"
class Db
{
public:
Db();
~Db();
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 AddItem(Item & item);
Error EditItemById(Item & item, bool with_subject = true);
Error EditItemByUrl(Item & item, bool with_subject = true);
void CheckAllUrlSubject();
void GetItems(std::vector<Item> & item_table, Item & item_ref);
void GetItem(std::vector<Item> & item_table, long id);
bool GetPriv(Item & item, long id);
Error EditPrivById(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
Error GetItem(long parent_id, const std::string & url, Item & item);
protected:
PGconn * pg_conn;
std::string db_database, db_user, db_pass;
void Connect();
void Close();
void AssertConnection();
std::string Escape(const std::string & s);
std::string Escape(const char * s);
PGresult * AssertQuery(const std::string & q);
void AssertResultStatus(PGresult * r, ExecStatusType t);
static int AssertColumn(PGresult * r, const char * column_name);
static const char * AssertValue(PGresult * r, int row, int col);
void ClearResult(PGresult * r);
long AssertCurrval(const char * table);
bool AddItemCreateUrlSubject(Item & item);
Error AddItemIntoContent(Item & item);
Error AddItemIntoItem(Item & item);
Error EditItemInItem(Item & item, bool with_subject);
Error EditItemInContent(Item & item);
Error EditItemGetId(Item & item);
Error EditItemGetContentId(Item & item);
void CheckAllUrlSubjectModifyItem(Item & item);
PGresult * GetItemsQuery(Item & item_ref);
bool DelItemDelItem(const Item & item);
void DelItemDelContent(const Item & item);
Error DelItemCountContents(const Item & item, long & contents);
struct ItemColumns
{
int id, user_id, group_id, privileges, url, type, parent_id, content_id, default_item, subject, content, content_type;
void SetColumns(PGresult * r);
void SetItem(PGresult * r, long row, Item & item);
};
}; // class Db
extern Db db;
#endif

View File

@@ -1,46 +0,0 @@
#include "db.h"
void Db::ItemColumns::SetColumns(PGresult * r)
{
// PQfnumber returns -1 if there is no such a column
id = PQfnumber(r, "id"); // !! why item.id doesn't work?
user_id = PQfnumber(r, "user_id");
group_id = PQfnumber(r, "group_id");
privileges = PQfnumber(r, "privileges");
url = PQfnumber(r, "url");
type = PQfnumber(r, "type");
parent_id = PQfnumber(r, "parent_id");
content_id = PQfnumber(r, "content_id");
default_item = PQfnumber(r, "default_item");
subject = PQfnumber(r, "subject");
content = PQfnumber(r, "content");
content_type = PQfnumber(r, "content_type");
}
void Db::ItemColumns::SetItem(PGresult * r, long row, Item & item)
{
if( id != -1 ) item.id = atol( Db::AssertValue(r, row, id) );
if( user_id != -1 ) item.user_id = atol( Db::AssertValue(r, row, user_id) );
if( group_id != -1 ) item.group_id = atol( Db::AssertValue(r, row, group_id) );
if( privileges != -1 ) item.privileges = atoi( Db::AssertValue(r, row, privileges) );
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( 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) );
}

View File

@@ -1,19 +1,55 @@
/* /*
* This file is a part of CMSLU -- Content Management System like Unix * This file is a part of Winix
* and is not publicly distributed * and is distributed under the 2-Clause BSD licence.
* * Author: Tomasz Sowa <t.sowa@ttmath.org>
* Copyright (c) 2008, Tomasz Sowa */
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/ */
#include "dircontainer.h" #include "dircontainer.h"
#include "log.h"
namespace Winix
{
std::wstring DirContainer::dir_etc = L"etc";
std::wstring DirContainer::dir_var = L"var";
DirContainer::DirContainer() DirContainer::DirContainer()
{ {
is_root = false; is_root = false;
is_etc = false;
is_var = false;
} }
@@ -22,11 +58,28 @@ DirContainer::Iterator DirContainer::GetRoot()
{ {
if( !is_root ) if( !is_root )
return table.end(); return table.end();
return table.begin() + root_index; return root_iter;
} }
DirContainer::Iterator DirContainer::GetEtc()
{
if( !is_etc )
return table.end();
return etc_iter;
}
DirContainer::Iterator DirContainer::GetVar()
{
if( !is_var )
return table.end();
return var_iter;
}
DirContainer::Iterator DirContainer::Begin() DirContainer::Iterator DirContainer::Begin()
{ {
@@ -42,7 +95,7 @@ DirContainer::Iterator DirContainer::End()
DirContainer::SizeType DirContainer::Size() DirContainer::SizeType DirContainer::Size()
{ {
return table.size(); return table.size(); // !! warning: it has O(n)
} }
bool DirContainer::Empty() bool DirContainer::Empty()
@@ -51,37 +104,132 @@ bool DirContainer::Empty()
} }
bool DirContainer::IsNameOfSpecialFolder(const std::wstring & name)
void DirContainer::PushBack(const Item & item)
{ {
bool rebuild_indexes = false; return name == dir_etc || name == dir_var;
if( table.size() == table.capacity() )
rebuild_indexes = true;
if( item.parent_id == -1 )
{
if( is_root )
log << log1 << "DirCont: more than one root dir - skipped, id: " << item.id << logend;
else
{
is_root = true;
root_index = table.size();
}
}
table.push_back(item);
log << log2 << "DirCont: added item, id: " << item.id << ", parent_id: " << item.parent_id << logend;
if( rebuild_indexes )
RebuildIndexes();
else
AddIndexes( --table.end() );
} }
// 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;
is_var = false;
if( !is_root )
return;
DirContainer::ParentIterator i = FindFirstChild(root_iter->id);
for( ; i!=ParentEnd() ; i = NextChild(i) )
{
if( i->second->url == dir_etc )
{
is_etc = true;
etc_iter = i->second;
}
else
if( i->second->url == dir_var )
{
is_var = true;
var_iter = i->second;
}
}
}
// 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 << log2 << "DirCont: added special folder: /etc" << logend;
}
if( item.parent_id==root_iter->id && item.url==dir_var )
{
is_var = true;
var_iter = iter;
log << log2 << "DirCont: added special folder: /var" << logend;
}
}
DirContainer::Iterator DirContainer::PushBack(const Item & item)
{
if( item.parent_id == -1 && is_root )
{
log << log1 << "DirCont: more than one root dir - skipped, id: " << item.id << logend;
return root_iter;
}
Iterator last_iter = table.insert(table.end(), item);
CheckSpecialFolder(item, last_iter);
log << log2 << "DirCont: added dir, url: " << item.url << ", id: " << item.id << ", parent_id: " << item.parent_id << logend;
table_id.insert( std::make_pair(last_iter->id, last_iter) );
table_parent.insert( std::make_pair(last_iter->parent_id, last_iter) );
log << log3 << "DirCont: added indexes to dir, id: " << last_iter->id << ", parent_id: " << last_iter->parent_id << logend;
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 = FindFirstChild(i->parent_id);
bool found = false;
for( ; p != table_parent.end() ; p = NextChild(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( IsNameOfSpecialFolder(i->url) )
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;
}
@@ -90,6 +238,7 @@ void DirContainer::Clear()
table.clear(); table.clear();
table_id.clear(); table_id.clear();
table_parent.clear(); table_parent.clear();
is_root = false;
} }
@@ -107,34 +256,6 @@ return i->second;
void DirContainer::AddIndexes(Iterator item)
{
table_id.insert( std::make_pair(item->id, item) );
table_parent.insert( std::make_pair(item->parent_id, item) );
log << log2 << "DirCont: added indexes to item, id: " << item->id << ", parent_id: " << item->parent_id << logend;
}
void DirContainer::RebuildIndexes()
{
Iterator i;
log << log2 << "DirCont: rebuilding indexes" << logend;
table_id.clear();
table_parent.clear();
for(i=table.begin() ; i!=table.end() ; ++i)
AddIndexes( i );
log << log2 << "DirCont: indexes rebuilt, table.size: " << table.size() << ", table_id.size: " << table_id.size() << ", table_parent.size: " << table_parent.size() << logend;
}
DirContainer::ParentIterator DirContainer::ParentBegin() DirContainer::ParentIterator DirContainer::ParentBegin()
{ {
return table_parent.begin(); return table_parent.begin();
@@ -160,7 +281,7 @@ bool DirContainer::ParentEmpty()
} }
DirContainer::ParentIterator DirContainer::FindFirstParent(long parent) DirContainer::ParentIterator DirContainer::FindFirstChild(long parent)
{ {
ParentIterator i = table_parent.lower_bound(parent); ParentIterator i = table_parent.lower_bound(parent);
@@ -171,7 +292,7 @@ return i;
} }
DirContainer::ParentIterator DirContainer::NextParent(ParentIterator i) DirContainer::ParentIterator DirContainer::NextChild(ParentIterator i)
{ {
if( i == table_parent.end() ) if( i == table_parent.end() )
return table_parent.end(); return table_parent.end();
@@ -184,3 +305,61 @@ DirContainer::ParentIterator DirContainer::NextParent(ParentIterator i)
return i; return i;
} }
bool DirContainer::DelById(long id)
{
TableId::iterator i = table_id.find(id);
if( i == table_id.end() )
{
log << log1 << "DirCont: delete: there is no directory with id: " << id << logend;
return false;
}
long parent_id = i->second->parent_id;
TableParent::iterator z = table_parent.lower_bound(parent_id);
bool found = false;
for( ; z != table_parent.end() && z->first == parent_id ; ++z )
{
if( z->second == i->second )
{
log << log2 << "DirCont: deleted directory id: " << id << ", url: " << i->second->url;
if( i->second->parent_id == -1 )
{
log << log2 << " (root directory)";
is_root = false;
}
log << log2 << logend;
table.erase(i->second);
log << log3 << "DirCont: deleted indexes into directory id: " << id << logend;
table_id.erase(i);
table_parent.erase(z);
found = true;
break;
}
}
if( !found )
{
log << log1 << "DirCont: can't find an index_parent into directory id: " << id << ", url: " << i->second->url << " (deleting skipped)" << logend;
return false;
}
return true;
}
} // namespace Winix

View File

@@ -1,28 +1,57 @@
/* /*
* This file is a part of CMSLU -- Content Management System like Unix * This file is a part of Winix
* and is not publicly distributed * and is distributed under the 2-Clause BSD licence.
* * Author: Tomasz Sowa <t.sowa@ttmath.org>
* Copyright (c) 2008, Tomasz Sowa */
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/ */
#ifndef headerfiledircontainer #ifndef headerfile_winix_core_dircontainer
#define headerfiledircontainer #define headerfile_winix_core_dircontainer
#include <vector> #include <list>
#include <map> #include <map>
#include "item.h" #include "item.h"
#include "log.h"
namespace Winix
{
class DirContainer class DirContainer
{ {
public: public:
typedef std::vector<Item> Table; typedef std::list<Item> Table;
typedef Table::iterator Iterator; typedef Table::iterator Iterator;
typedef Table::size_type SizeType; typedef Table::size_type SizeType;
typedef std::map<long, Iterator> TableId; typedef std::map<long, Iterator> TableId;
typedef std::multimap<long, Iterator> TableParent; typedef std::multimap<long, Iterator> TableParent;
@@ -33,28 +62,34 @@ public:
DirContainer(); DirContainer();
Iterator GetRoot(); Iterator GetRoot();
Iterator GetEtc();
Iterator GetVar();
Iterator Begin(); Iterator Begin();
Iterator End(); Iterator End();
SizeType Size(); SizeType Size();
bool Empty(); bool Empty();
void PushBack(const Item & item); Iterator PushBack(const Item & item);
bool ChangeParent(long dir_id, long new_parent_id);
void Clear(); void Clear();
Iterator FindId(long id); Iterator FindId(long id);
ParentIterator ParentBegin(); bool DelById(long id);
ParentIterator ParentBegin(); // IMPROVE ME: may it should be renamed to ChildBegin() similarly as FindFirstChild() ?
ParentIterator ParentEnd(); ParentIterator ParentEnd();
ParentSizeType ParentSize(); ParentSizeType ParentSize();
bool ParentEmpty(); bool ParentEmpty();
ParentIterator FindFirstParent(long parent); ParentIterator FindFirstChild(long parent);
ParentIterator NextParent(ParentIterator pi); ParentIterator NextChild(ParentIterator pi);
bool IsNameOfSpecialFolder(const std::wstring & name);
void FindSpecialFolders();
private: private:
void AddIndexes(Iterator item); void CheckSpecialFolder(const Item & item, Iterator iter);
void RebuildIndexes();
// main table with dirs // main table with dirs
Table table; Table table;
@@ -62,13 +97,32 @@ private:
// true if there is a root dir in the table // true if there is a root dir in the table
bool is_root; bool is_root;
// root dir // root
SizeType root_index; Iterator root_iter;
// true if there is a etc dir in the table
bool is_etc;
// etc
Iterator etc_iter;
// true if there is a var dir in the table
bool is_var;
// var
Iterator var_iter;
// indexes // indexes
TableId table_id; TableId table_id;
TableParent table_parent; TableParent table_parent;
// names of folders
static std::wstring dir_etc, dir_var;
}; };
} // namespace Winix
#endif #endif

View File

@@ -1,41 +1,110 @@
/* /*
* This file is a part of CMSLU -- Content Management System like Unix * This file is a part of Winix
* and is not publicly distributed * and is distributed under the 2-Clause BSD licence.
* * Author: Tomasz Sowa <t.sowa@ttmath.org>
* Copyright (c) 2008, Tomasz Sowa */
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/ */
#include "dirs.h" #include "dirs.h"
#include "error.h"
#include "log.h"
namespace Winix
{
void Dirs::SetDb(Db * pdb)
{
db = pdb;
}
void Dirs::SetCur(Cur * pcur)
{
cur = pcur;
}
void Dirs::SetNotify(Notify * pnotify)
{
notify = pnotify;
}
void Dirs::Clear() void Dirs::Clear()
{ {
dir_table.Clear(); dir_tab.Clear();
} }
bool Dirs::HasReadExecAccessForRoot(const Item & item)
{
// there must be at least one 'x' (for the root)
return (item.privileges & 01111) != 0;
}
void Dirs::CheckRootDir() void Dirs::CheckRootDir()
{ {
DirContainer::ParentIterator i; DirContainer::Iterator i = dir_tab.GetRoot();
long roots = 0;
if( i != dir_tab.End() )
for( i=dir_table.FindFirstParent(-1) ; i!=dir_table.ParentEnd() ; i=dir_table.NextParent(i) )
++roots;
if( roots == 0 )
{ {
log << log1 << "Dirs: there is no a root dir in the database" << logend; if( !HasReadExecAccessForRoot(*i) )
Clear(); {
i->privileges = 07555;
log << log1 << "Dirs: there is no access for a root (admin) to the root dir, setting 07555 for the root directory" << logend;
db->EditPrivById(*i, i->id);
}
return;
} }
else
if( roots > 1 )
log << log1 << "Dirs: there is no a root directory in the database (creating one)" << logend;
Item root;
root.type = Item::dir;
root.parent_id = -1;
root.user_id = -1;
root.group_id = -1;
root.privileges = 07555;
// !! 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) == WINIX_ERR_OK )
{ {
log << log1 << "Dirs: there are more than one root dir in the database" << logend; dir_tab.PushBack(root);
Clear();
} }
} }
@@ -46,40 +115,13 @@ void Dirs::ReadDirs()
{ {
Clear(); Clear();
db.GetDirs(dir_table); db->GetDirs(dir_tab);
CheckRootDir(); CheckRootDir();
dir_tab.FindSpecialFolders();
} }
bool Dirs::GetRootDir(Item ** item) bool Dirs::ExtractName(const wchar_t * & s, std::wstring & name)
{
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;
}
bool Dirs::ExtractName(const char * & s, std::string & name)
{ {
name.clear(); name.clear();
@@ -94,69 +136,13 @@ 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) bool Dirs::IsDir(long id)
{ {
DirContainer::Iterator i = dir_table.FindId(id); DirContainer::Iterator i = dir_tab.FindId(id);
if( i == dir_table.End() ) if( i == dir_tab.End() )
return false; return false;
return true; return true;
@@ -164,133 +150,240 @@ return true;
// !! dac clearowanie childs_tab
bool Dirs::GetDirChilds(long parent, std::vector<Item> & childs_table) // !! ewentualnie mozna dodac trzeci domyslny parametr bool clear_tab = true
bool Dirs::GetDirChilds(long parent, std::vector<Item*> & childs_tab)
{ {
if( parent != -1 && !IsDir(parent) ) if( parent != -1 && !IsDir(parent) )
return false; return false;
DirContainer::ParentIterator i = dir_table.FindFirstParent(parent); DirContainer::ParentIterator i = dir_tab.FindFirstChild(parent);
for( ; i != dir_table.ParentEnd() ; i = dir_table.NextParent(i) ) for( ; i != dir_tab.ParentEnd() ; i = dir_tab.NextChild(i) )
childs_table.push_back( *i->second ); childs_tab.push_back( &(*i->second) );
return true; return true;
} }
bool Dirs::GetDirChilds(long parent, std::vector<Item*> & childs_table) DirContainer::ParentIterator Dirs::FindFirstChild(long parent_id)
{ {
if( parent != -1 && !IsDir(parent) ) DirContainer::ParentIterator i = dir_tab.FindFirstChild(parent_id);
return false;
return i;
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;
} }
DirContainer::ParentIterator Dirs::NextChild(DirContainer::ParentIterator i)
{
return dir_tab.NextChild(i);
}
// dodatkowo moze metoda AppendPath dodajaca sciezke do biezacego stringa?
DirContainer::ParentIterator Dirs::ParentEnd()
{
return dir_tab.ParentEnd();
}
// !! dodatkowo moze metoda AppendPath dodajaca sciezke do biezacego stringa?
// albo tutaj stringa nie czyscic? // albo tutaj stringa nie czyscic?
// O(m * log n) (m- how many parts are in 'id') // O(m * log n) (m- how many parts are in 'id')
bool Dirs::MakePath(long id, std::string & path) // path with a slash at the end and at the beginning
bool Dirs::MakePath(long id, std::wstring & path, bool clear_path)
{ {
DirContainer::Iterator i; DirContainer::Iterator i;
path = '/'; if( clear_path )
path.clear();
temp_path = '/';
while( true ) while( true )
{ {
i = dir_table.FindId(id); i = dir_tab.FindId(id);
if( i == dir_table.End() ) if( i == dir_tab.End() ||
i->parent_id == id ) // means a loop (something wrong in the db)
{
// we don't change path if there is no such a directory
return false; return false;
}
if( i->parent_id == -1 ) if( i->parent_id == -1 )
{
path += temp_path;
return true; return true;
}
id = i->parent_id; id = i->parent_id;
temp_path.insert(0, i->url);
path.insert(0, i->url); temp_path.insert(temp_path.begin(), '/');
path.insert(path.begin(), '/');
} }
} }
// with exceptions
Item * Dirs::GetDirT(const std::string & path) void Dirs::MakePath(const std::vector<Item*> dir_tab, std::wstring & path, bool clear_path)
{ {
Item * pitem; if( clear_path )
path.clear();
if( !GetDir(path, &pitem) )
throw Error(Error::incorrect_dir);
return pitem;
}
for(size_t i=0 ; i<dir_tab.size() ; ++i)
Item * Dirs::GetDirT(const std::string & name, long parent) {
{ path += dir_tab[i]->url;
Item * pitem; path += '/';
}
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;
} }
// !! nowy interfejs size_t Dirs::DirLevel(long id)
{
DirContainer::Iterator i;
size_t level = 0;
while( true )
{
i = dir_tab.FindId(id);
if( i == dir_tab.End() ||
i->parent_id == id ) // means a loop (something wrong in the db)
{
return level;
}
if( i->parent_id == -1 )
return level;
id = i->parent_id;
level += 1;
}
}
bool Dirs::IsChild(long parent_id, long child_id)
{
if( child_id == parent_id )
return false;
DirContainer::Iterator i;
while( child_id != -1 )
{
i = dir_tab.FindId(child_id);
if( i == dir_tab.End() )
return false;
if( i->parent_id == parent_id )
return true;
child_id = i->parent_id;
}
return false;
}
bool Dirs::ChangeParent(long dir_id, long new_parent_id)
{
return dir_tab.ChangeParent(dir_id, new_parent_id);
}
/*
checking whether dir_id has a parent parent_id (somewhere in the path)
*/
bool Dirs::HasParent(long dir_id, long parent_id)
{
DirContainer::Iterator i;
while( true )
{
i = dir_tab.FindId(dir_id);
if( i==dir_tab.End() || i->parent_id==-1 )
return false;
if( i->parent_id == parent_id )
return true;
dir_id = i->parent_id;
}
}
bool Dirs::CreateDirTab(long dir_id, std::vector<Item*> & out_dir_tab)
{
DirContainer::Iterator i;
out_dir_tab.clear();
do
{
i = dir_tab.FindId(dir_id);
if( i == dir_tab.End() )
return false;
if( out_dir_tab.empty() )
out_dir_tab.insert(out_dir_tab.end(), &(*i)); // !! I am not sure whether begin() can be used on an empty container
else
out_dir_tab.insert(out_dir_tab.begin(), &(*i));
dir_id = i->parent_id;
}
while( dir_id != -1 );
return true;
}
Item * Dirs::GetRootDir() Item * Dirs::GetRootDir()
{ {
DirContainer::Iterator root = dir_table.GetRoot(); DirContainer::Iterator root = dir_tab.GetRoot();
if( root == dir_table.End() ) if( root == dir_tab.End() )
return 0; return 0;
return &(*root); return &(*root);
} }
Item * Dirs::GetDir(const std::string & name, long parent) Item * Dirs::GetEtcDir()
{ {
DirContainer::ParentIterator i = dir_table.FindFirstParent(parent); DirContainer::Iterator etc = dir_tab.GetEtc();
for( ; i!=dir_table.ParentEnd() ; i = dir_table.NextParent(i) ) if( etc == dir_tab.End() )
return 0;
return &(*etc);
}
Item * Dirs::GetVarDir()
{
DirContainer::Iterator etc = dir_tab.GetVar();
if( etc == dir_tab.End() )
return 0;
return &(*etc);
}
Item * Dirs::GetDir(const wchar_t * name, long parent)
{
DirContainer::ParentIterator i = dir_tab.FindFirstChild(parent);
for( ; i!=dir_tab.ParentEnd() ; i = dir_tab.NextChild(i) )
if( i->second->url == name ) if( i->second->url == name )
return &(*i->second); return &(*i->second);
@@ -298,40 +391,399 @@ return 0;
} }
Item * Dirs::GetDir(const std::wstring & name, long parent)
Item * Dirs::GetDir(const std::string & path)
{ {
DirContainer::Iterator root = dir_table.GetRoot(); return GetDir(name.c_str(), parent);
}
Item * Dirs::GetDir(const wchar_t * path)
{
if( *path == 0 )
return 0;
DirContainer::Iterator root = dir_tab.GetRoot();
if( root == dir_table.End() ) if( root == dir_tab.End() )
// ops, we do not have a root dir // ops, we do not have a root dir
return 0; return 0;
Item * pitem = &(*root); Item * pitem = &(*root);
const wchar_t * s = path;
std::string name;
const char * s = path.c_str();
while( ExtractName(s, name) ) while( ExtractName(s, get_dir_temp) )
{ {
pitem = GetDir(name, pitem->id); pitem = GetDir(get_dir_temp, pitem->id);
if( !pitem ) if( !pitem )
return 0; return 0;
} }
return pitem; return pitem;
} }
Item * Dirs::GetDir(const std::wstring & path)
{
return GetDir(path.c_str());
}
Item * Dirs::GetDir(long id) Item * Dirs::GetDir(long id)
{ {
DirContainer::Iterator i = dir_table.FindId(id); DirContainer::Iterator i = dir_tab.FindId(id);
if( i == dir_table.End() ) if( i == dir_tab.End() )
return 0; return 0;
return &(*i); return &(*i);
} }
Item * Dirs::AddDir(const Item & item)
{
return &(*dir_tab.PushBack(item));
}
size_t Dirs::AnalyzeDir(Item * pdir, const std::wstring & path, long & dir_id, std::wstring & 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::wstring & path, long & dir_id, std::wstring & dir, std::wstring & 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;
}
// current_dir_tab can be the same container as out_dir_tab
void Dirs::CopyDirTab(const std::vector<Item*> & in, std::vector<Item*> & out)
{
if( &in != &out )
{
out.resize(in.size());
for(size_t i=0 ; i<in.size() ; ++i)
out[i] = in[i];
}
}
/*
!! IMPROVE ME
may dir_tab can be empty when link_to is not relative?
and now the algorith doesn't check if link_to is not relative (it only uses dir_tab)
*/
bool Dirs::AnalyzeDir(std::vector<Item*> & dir_tab, const std::wstring & link_to, size_t & i)
{
size_t old_i;
i = 0;
if( dir_tab.empty() )
return false;
while( true )
{
// skipping slashes
for( ; i<link_to.size() && link_to[i] == '/' ; ++i);
if( i == link_to.size() )
return true; // end of the path
// creating a name
old_i = i;
analyze_temp.clear();
for( ; i<link_to.size() && link_to[i] != '/' ; ++i)
analyze_temp += link_to[i];
if( analyze_temp == L".." )
{
if( dir_tab.size() <= 1 )
return false;
dir_tab.pop_back();
}
else
if( analyze_temp != L"." )
{
Item * pdir = GetDir(analyze_temp, dir_tab.back()->id);
if( !pdir )
{
i = old_i;
return true; // analyze_temp is not a directory
}
dir_tab.push_back(pdir);
}
}
}
int Dirs::FollowLink(std::vector<Item*> & dir_tab, const std::wstring & link_to, std::wstring & out_item)
{
size_t i;
if( !AnalyzeDir(dir_tab, link_to, i) )
return 2; // incorrect link_to
if( i < link_to.size() )
{
// checking if at least one slash has left
for(size_t a=i ; a < link_to.size() ; ++a)
if( link_to[a] == '/' )
return 2; // there is not such a directory
// the rest of the path is a file name
out_item = link_to.c_str() + i;
return 1;
}
return 0;
}
/*
return codes:
ok:
0 - the link_to is a path to a directory (out_item skipped, out_dir_tab will not be empty)
1 - the link_to is a path to a file (out_item is used, out_dir_tab will not be empty)
error:
2 - incorrect link_to
3 - there is not a root dir
4 - current_dir_tab was empty
current_dir_tab can be the same container as out_dir_tab
link_to can be a relative path (without the first slash) and can contain ".." or "."
*/
int Dirs::FollowLink(const std::vector<Item*> & current_dir_tab, const std::wstring & link_to,
std::vector<Item*> & out_dir_tab, std::wstring & out_item)
{
temp_link_to = link_to; // link_to can be from the out_item and would be cleared next
out_item.clear();
if( current_dir_tab.empty() )
return 4;
if( temp_link_to.empty() )
{
CopyDirTab(current_dir_tab, out_dir_tab);
return 0;
}
if( temp_link_to[0] == '/' )
{
// temp_link_to is an absolute path
Item * pdir = GetRootDir();
if( !pdir )
return 3;
out_dir_tab.clear();
out_dir_tab.push_back(pdir);
}
else
{
// temp_link_to is a relative path
CopyDirTab(current_dir_tab, out_dir_tab);
}
return FollowLink(out_dir_tab, temp_link_to, out_item);
}
void Dirs::SplitPath(const std::wstring & path, std::wstring & dir, std::wstring & file)
{
std::wstring::size_type i;
dir.clear();
file.clear();
if( path.empty() )
// !! moze dir ustawic na '/' ?
return;
for( i=path.size()-1 ; i>0 && path[i]!='/' ; --i);
if( path[i] != '/' )
{
// we do not have any slashes '/'
file = path;
return;
}
dir.assign(path, 0, i + 1); // +1 means with a slash at the end
if( i < path.size() - 1 )
file.assign(path, i+1, path.size() - i - 1);
}
// !! dodac kasowanie z bazy
bool Dirs::DelDir(long dir_id)
{
return dir_tab.DelById(dir_id);
}
Error Dirs::AddDirectory(Item & item, bool add_to_dir_tab, Item ** pdir, int notify_code)
{
if( pdir )
*pdir = 0;
if( item.type != Item::dir )
return WINIX_ERR_DIR_EXPECTED;
Error status = db->AddItem(item);
if( status == WINIX_ERR_OK )
{
Item * d = AddDir(item);
if( add_to_dir_tab && !cur->request->dir_tab.empty() && cur->request->dir_tab.back()->id == item.parent_id )
cur->request->dir_tab.push_back(d);
if( pdir )
*pdir = d;
if( notify_code )
notify->ItemChanged(notify_code, item);
}
return status;
}
Item * Dirs::CreateVarDir()
{
Item * var = GetVarDir();
if( var )
return var;
Item v;
Item * root = GetRootDir();
if( root )
{
v.parent_id = root->id;
v.user_id = root->user_id;
v.group_id = root->group_id;
v.privileges = root->privileges;
v.subject = L"var";
v.url = L"var";
v.type = Item::dir;
AddDirectory(v, false, &var);
}
return var;
}
// printing first and last slash
void Dirs::LogDir(const std::vector<Item*> & dir_tab)
{
log << '/';
// skipping the first (root) directory
for(size_t i=1 ; i<dir_tab.size() ; ++i)
log << dir_tab[i]->url << '/';
}
} // namespace Winix

View File

@@ -1,89 +1,152 @@
/* /*
* This file is a part of CMSLU -- Content Management System like Unix * This file is a part of Winix
* and is not publicly distributed * and is distributed under the 2-Clause BSD licence.
* * Author: Tomasz Sowa <t.sowa@ttmath.org>
* Copyright (c) 2008, Tomasz Sowa */
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/ */
#ifndef headerfiledirs #ifndef headerfile_winix_core_dirs
#define headerfiledirs #define headerfile_winix_core_dirs
#include <vector> #include <vector>
#include <map> #include <map>
#include <string> #include <string>
#include "item.h"
#include "error.h"
#include "log.h"
#include "db.h"
#include "dircontainer.h"
#include "item.h"
#include "dircontainer.h"
#include "db/db.h"
#include "request.h"
#include "notify/notify.h"
namespace Winix
{
// !! IMPROVE ME
// we do not support '..' in a path (for simplicity and security reasons)
// (we will support '..' in the future)
class Dirs class Dirs
{ {
private:
public: // !! temporarily
DirContainer dir_table;
bool ExtractName(const char * & s, std::string & name);
void CheckRootDir();
public: public:
void Clear(); void Clear();
void ReadDirs(); void ReadDirs();
// without any exceptions void SetCur(Cur * pcur);
// these methods return false in a case the path or name (with a specific parent) are invalid void SetDb(Db * pdb);
// we do not support '..' in a path (for security reason) void SetNotify(Notify * pnotify);
bool IsDir(long id);
bool GetRootDir(Item ** item);
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 // these methods return false if there is no such a dir
bool GetDirChilds(long parent, std::vector<Item> & childs_table); // only returns dir-children bool IsDir(long dir_id);
bool GetDirChilds(long parent_id, std::vector<Item*> & childs_tab); // !! zamienic na GetChilds()
bool MakePath(long dir_id, std::wstring & path, bool clear_path = true);
void MakePath(const std::vector<Item*> dir_tab, std::wstring & path, bool clear_path = true);
bool ChangeParent(long dir_id, long new_parent_id);
bool GetDirChilds(long parent, std::vector<Item*> & childs_table); // only returns dir-children bool HasParent(long dir_id, long parent_id);
bool MakePath(long id, std::string & path); bool DelDir(long dir_id);
// if returns true then out_dir_tab is not empty
bool CreateDirTab(long dir_id, std::vector<Item*> & out_dir_tab);
void LogDir(const std::vector<Item*> & dir_tab);
int AnalyzePath(const std::wstring & path, long & dir_id, std::wstring & dir, std::wstring & file);
int FollowLink(const std::vector<Item*> & current_dir_tab, const std::wstring & link_to,
std::vector<Item*> & out_dir_tab, std::wstring & out_item);
static void SplitPath(const std::wstring & path, std::wstring & dir, std::wstring & file);
DirContainer::ParentIterator FindFirstChild(long parent_id);
DirContainer::ParentIterator NextChild(DirContainer::ParentIterator i);
DirContainer::ParentIterator ParentEnd(); // !! pozostalo do zamiany na child
// with an Error exception // these methods return null if there is no such a dir
// if the path or name are invalid these methods throw an exception // !! zmienic nazwy wskazujace ze operujemy tylko na lokalnej tablicy
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
Item * GetRootDir(); Item * GetRootDir();
Item * GetDir(const std::string & name, long parent); Item * GetEtcDir();
Item * GetDir(const std::string & path); Item * GetVarDir();
Item * GetDir(const wchar_t * name, long parent);
Item * GetDir(const std::wstring & name, long parent);
Item * GetDir(const wchar_t * path);
Item * GetDir(const std::wstring & path);
Item * GetDir(long id); Item * GetDir(long id);
Item * AddDir(const Item & item);
void CheckRootDir();
Item * CreateVarDir();
// !! jak juz wczesniejsze nazwy beda zmienione to tutaj damy AddDir() /AddDir() juz istnieje przeciez?/
Error AddDirectory(Item & item, bool add_to_dir_tab = false, Item ** pdir = 0, int notify_code = 0);
// returns how many levels of directories there are
// "/" -> 0 (root dir)
// "/abc" -> 1
// "/abc/def" -> 2
size_t DirLevel(long id);
// checking if child_id is really a child of parent_id
bool IsChild(long parent_id, long child_id);
private:
Cur * cur;
Db * db;
Notify * notify;
DirContainer dir_tab;
std::wstring temp_path;
std::wstring temp_link_to;
size_t AnalyzeDir(Item * pdir, const std::wstring & path, long & dir_id, std::wstring & dir);
bool AnalyzeDir(std::vector<Item*> & dir_tab, const std::wstring & link_to, size_t & i);
std::wstring analyze_temp;
std::wstring get_dir_temp;
void CopyDirTab(const std::vector<Item*> & in, std::vector<Item*> & out);
int FollowLink(std::vector<Item*> & dir_tab, const std::wstring & link_to, std::wstring & out_item);
bool ExtractName(const wchar_t * & s, std::wstring & name);
bool HasReadExecAccessForRoot(const Item & item);
}; };
} // namespace Winix
#endif #endif

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, 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 );
}

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, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfiledone
#define headerfiledone
// what has been done
class Done
{
public:
enum Code
{
none = 0,
added_item,
edited_item,
deleted_item,
privileged_item,
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

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, 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;
}

View File

@@ -1,80 +1,111 @@
/* /*
* This file is a part of CMSLU -- Content Management System like Unix * This file is a part of Winix
* and is not publicly distributed * and is distributed under the 2-Clause BSD licence.
* * Author: Tomasz Sowa <t.sowa@ttmath.org>
* Copyright (c) 2008, Tomasz Sowa */
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/ */
#ifndef headerfileerror #ifndef headerfile_winix_core_error
#define headerfileerror #define headerfile_winix_core_error
#include <iostream>
#include "log.h"
namespace Winix
class Error
{ {
public:
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 = 1000
};
#define WINIX_ERR_OK 0
Error(); //#define WINIX_ERR_INCORRECT_PATH 1
Error(Code c);
Error(int i);
Error(const Error & e);
Error & operator=(Code c);
Error & operator=(const Error & e);
operator int() const; //#define WINIX_ERR_NO_POSTVAR 2
#define WINIX_ERR_INCORRECT_DIR 3
bool operator==(Code c) const; #define WINIX_ERR_CANT_CHANGE_USER 4
bool operator!=(Code c) const; #define WINIX_ERR_CANT_CHANGE_GROUP 5
bool operator==(const Error & e) const; #define WINIX_ERR_CANT_CHANGE_PRIVILEGES 6
bool operator!=(const Error & e) const; #define WINIX_ERR_PERMISSION_DENIED 7
#define WINIX_ERR_NO_ROOT_DIR 8
friend std::ostream & operator<<(std::ostream & out, const Error & e); #define WINIX_ERR_NO_FUNCTION 9
friend Log & operator<<(Log & out, const Error & e);
#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
private: #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
Code code; #define WINIX_ERR_NO_TICKET 24
}; //#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
#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
#define WINIX_ERR_FILE_EXPECTED 107
#define WINIX_ERR_DIR_EXPECTED 108
//#define WINIX_ERR_UNKNOWN 1000
#define WINIX_NOTHING_TO_DO 109
#define WINIX_ERR_INCORRECT_URI 110
#define WINIX_ERR_INTERNAL_ERROR 2000
typedef int Error;
} // namespace Winix
#endif #endif

View File

@@ -1,53 +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 "function.h"
Function::Function()
{
code = none;
}
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;
}

View File

@@ -1,52 +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 headerfilefunction
#define headerfilefunction
#include <iostream>
#include "log.h"
#include "item.h"
class Function
{
public:
enum Code
{
none,
ls,
cat,
node,
emacs,
privileges,
rm,
login,
logout
};
Code code;
Item item;
Function();
Function(const Function & f);
Function & operator=(const Function & f);
};
#endif

View File

@@ -1,181 +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 "functionparser.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();
}

View File

@@ -1,45 +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 headerfilefunctionparser
#define headerfilefunctionparser
#include "request.h"
#include "log.h"
#include "item.h"
#include "error.h"
#include "data.h"
#include "db.h"
class FunctionParser
{
GetTable::size_type get_index;
GetTable::size_type get_table_len;
void SkipEmptyString(const char * msg);
void ParseDirectories();
void ParseItem();
void ParseFunction();
void ParseParams();
public:
void Parse();
};
#endif

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, 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 = Function::ls;
f.item.url = "list";
table.insert( std::make_pair(f.item.url, f) );
f.code = Function::cat;
f.item.url = "wyswietl";
table.insert( std::make_pair(f.item.url, f) );
f.code = Function::node;
f.item.url = "node";
table.insert( std::make_pair(f.item.url, f) );
f.code = Function::emacs;
f.item.url = "edytuj";
table.insert( std::make_pair(f.item.url, f) );
f.code = Function::privileges;
f.item.url = "uprawnienia";
table.insert( std::make_pair(f.item.url, f) );
f.code = Function::rm;
f.item.url = "usun";
table.insert( std::make_pair(f.item.url, f) );
f.code = Function::logout;
f.item.url = "wyloguj";
table.insert( std::make_pair(f.item.url, f) );
f.code = Function::login;
f.item.url = "login";
table.insert( std::make_pair(f.item.url, f) );
}
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(Function::Code code)
{
Table::iterator i = table.begin();
for( ; i != table.end() ; ++i )
{
if( i->second.code == code )
return &(i->second);
}
return 0;
}

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, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilefunctions
#define headerfilefunctions
#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(Function::Code code);
};
#endif

View File

@@ -1,57 +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 headerfilegetparser
#define headerfilegetparser
#include "httpsimpleparser.h"
#include "requesttypes.h"
class GetParser : public HttpSimpleParser
{
const char * get_string;
GetTable & get_table;
protected:
virtual int GetChar()
{
if( !get_string || *get_string == 0 )
return -1;
return (int)(unsigned char)*(get_string++);
}
virtual void Parameter(std::string &, std::string & value)
{
get_table.push_back(value);
log << log2 << "Get, value: \"" << value << "\"" << logend;
}
public:
GetParser(const char * get_string_, GetTable & get_table_) : get_string(get_string_), get_table(get_table_)
{
HttpSimpleParser::separator = '/';
HttpSimpleParser::read_name = false;
if( get_string && *get_string == separator ) // one '/' at the beginning
++get_string;
}
};
#endif

View File

@@ -1,24 +1,53 @@
/* /*
* This file is a part of CMSLU -- Content Management System like Unix * This file is a part of Winix
* and is not publicly distributed * and is distributed under the 2-Clause BSD licence.
* * Author: Tomasz Sowa <t.sowa@ttmath.org>
* Copyright (c) 2008, Tomasz Sowa */
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/ */
#ifndef headerfilegroup #ifndef headerfile_winix_core_group
#define headerfilegroup #define headerfile_winix_core_group
#include <string> #include <string>
#include <vector> #include <vector>
namespace Winix
{
struct Group struct Group
{ {
long id; long id;
std::string name; // group name std::wstring name; // group name
std::vector<long> members; // users id std::vector<long> members; // users id
Group() Group()
@@ -38,6 +67,8 @@ struct Group
} // namespace Winix
#endif #endif

View File

@@ -1,16 +1,42 @@
/* /*
* This file is a part of CMSLU -- Content Management System like Unix * This file is a part of Winix
* and is not publicly distributed * and is distributed under the 2-Clause BSD licence.
* * Author: Tomasz Sowa <t.sowa@ttmath.org>
* Copyright (c) 2008, Tomasz Sowa */
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/ */
#include "groups.h" #include "groups.h"
namespace Winix
{
@@ -26,11 +52,11 @@ void Groups::Clear()
} }
void Groups::ReadGroups() void Groups::ReadGroups(Db * db)
{ {
Clear(); Clear();
db.GetGroups(table); db->GetGroups(table);
} }
@@ -45,7 +71,7 @@ return &(*i);
} }
Group * Groups::GetGroup(const std::string & name) Group * Groups::GetGroup(const std::wstring & name)
{ {
Table::Iterator i = table.FindName(name); Table::Iterator i = table.FindName(name);
@@ -56,7 +82,7 @@ return &(*i);
} }
long Groups::GetGroupId(const std::string & name) long Groups::GetGroupId(const std::wstring & name)
{ {
Group * pgroup = GetGroup(name); Group * pgroup = GetGroup(name);
@@ -88,31 +114,13 @@ Groups::SizeType Groups::Size()
} }
Group & Groups::operator[](Groups::SizeType pos) bool Groups::Remove(long group_id)
{ {
return table[pos]; return table.Remove(group_id);
} }
} // namespace Winix

View File

@@ -1,19 +1,50 @@
/* /*
* This file is a part of CMSLU -- Content Management System like Unix * This file is a part of Winix
* and is not publicly distributed * and is distributed under the 2-Clause BSD licence.
* * Author: Tomasz Sowa <t.sowa@ttmath.org>
* Copyright (c) 2008, Tomasz Sowa */
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/ */
#ifndef headerfilegroups #ifndef headerfile_winix_core_groups
#define headerfilegroups #define headerfile_winix_core_groups
#include <map> #include <map>
#include "group.h" #include "group.h"
#include "db.h"
#include "ugcontainer.h" #include "ugcontainer.h"
#include "db/db.h"
namespace Winix
{
class Groups class Groups
@@ -29,22 +60,21 @@ public:
Groups(); Groups();
void Clear(); void Clear();
void ReadGroups(); void ReadGroups(Db * db);
Group * GetGroup(long group_id); Group * GetGroup(long group_id);
Group * GetGroup(const std::string & name); Group * GetGroup(const std::wstring & name);
long GetGroupId(const std::string & name); long GetGroupId(const std::wstring & name);
Iterator Begin(); Iterator Begin();
Iterator End(); Iterator End();
SizeType Size(); SizeType Size();
Group & operator[](SizeType pos); bool Remove(long group_id);
}; };
} // namespace Winix

1524
core/htmlfilter.cpp Executable file

File diff suppressed because it is too large Load Diff

346
core/htmlfilter.h Executable file
View File

@@ -0,0 +1,346 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_htmlfilter
#define headerfile_winix_core_htmlfilter
#include <string>
#include <map>
#include <vector>
#include <algorithm>
namespace Winix
{
// max length of a name of a html tag (with terminating null)
#define WINIX_HTMLFILTER_ITEM_NAME_MAXLEN 30
// max length of a html lang attribute (e.g. "en", "pl")
#define WINIX_HTMLFILTER_ITEM_LANG_MAXLEN 10
#define WINIX_HTMLFILTER_ATTR_NAME_MAXLEN 40
#define WINIX_HTMLFILTER_ATTR_VALUE_MAXLEN 500
// 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_NAME_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:
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 wchar_t * in, std::wstring & out);
void Filter(const std::wstring & in, std::wstring & out);
// insert a white space into long words
// (only between html tags)
// skipped in such tags: script, pre, textarea
// break_after - after how many characters insert a space (0 - off)
void BreakWord(size_t break_after_);
// insert a new line character into long lines
// (only between html tags)
// skipped in such tags: script, pre, textarea
// wrap_line - after how many characters wrap a line (0 - off)
// lines are wrapped only in 'body' tag (useful for text in 'title' tag which is in 'head' section)
void WrapLine(size_t wrap_line_);
// 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);
// set a name of a html tag which will be used as 'nofilter' tag
// elements between such tags are not filtered (similarly as in <pre> and <textarea>)
// these tags (opening and closing) will no be placed in the html output
void SetNoFilterTag(const std::wstring & tag_name);
// orphans are checked only in 'body' tag
void AssignOrphans(const wchar_t * lang_code, const std::vector<std::wstring> & otab);
void AssignOrphans(const std::wstring & lang_code, const std::vector<std::wstring> & otab);
void ClearOrphans();
// 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 OrphansMode(OrphanMode mode = orphan_nbsp);
// skipping some unsafe tags
// (script, iframe, frame, frameset, applet, head, meta, html, link, body, ...)
void SafeMode(bool safe_mode_);
protected:
// orphans for one language
struct Orphans
{
std::vector<std::wstring> tab;
size_t max_len;
};
// orphans for all languages
// map<language_code, Orphans>
typedef std::map<std::wstring, Orphans> OrphansTab;
OrphansTab orphans_tab;
// html <nofilter> tag name
std::wstring no_filter_tag;
struct Item
{
std::wstring name; // max size: WINIX_HTMLFILTER_ITEM_NAME_MAXLEN
enum Type
{
opening, /* sample: <h1> */
closing, /* sample: </h1> */
simple, /* sample: <br/> */
special, /* sample: <!doctype> */
none
} type;
// is there a new line after this tag
bool new_line;
// current orphans table
// (will be propagated)
Orphans * porphans;
// this item or one from its parents is a 'body' html tag
// (will be propagated)
bool has_body_tag;
void Clear();
Item();
};
/*
virtual methods
*/
virtual void Init();
virtual void Uninit();
virtual bool IsOpeningTagMark();
virtual bool IsOpeningCommentaryTagMark();
virtual bool IsClosingTagMark();
virtual bool IsClosingXmlSimpleTagMark();
virtual bool IsValidCharForName(int c);
virtual bool IsValidCharForAttrName(int c);
virtual void CheckExceptions();
virtual bool SkipCommentaryTagIfExists();
virtual void Put(wchar_t c);
virtual void Put(const wchar_t * str);
virtual void Put(const wchar_t * str, const wchar_t * end);
virtual void Put(const std::wstring & str);
virtual void PutOpeningTagMark();
virtual void PutClosingTagMark();
virtual bool PutOpeningTag();
virtual void PutClosingTag(const wchar_t * tag);
virtual void PutNormalText(const wchar_t * str, const wchar_t * end);
virtual void ReadNormalTextSkipWhite(const wchar_t * & start, const wchar_t * & last_non_white);
/*
others
*/
Item & GetItem(size_t i);
Item & LastItem();
wchar_t ToLower(wchar_t c);
void ToLower(std::wstring & str);
bool IsNameEqual(const wchar_t * name1, const wchar_t * name2);
bool IsNameEqual(const wchar_t * name1, const std::wstring & name2);
bool IsNameEqual(const std::wstring & name1, const wchar_t * name2);
bool IsNameEqual(const std::wstring & name1, const std::wstring & name2);
bool IsNameEqual(const wchar_t * name1, const wchar_t * name2, size_t len);
bool IsNameEqual(const wchar_t * name1, const std::wstring & name2, size_t len);
bool IsNameEqual(const std::wstring & name1, const wchar_t * name2, size_t len);
bool IsNameEqual(const std::wstring & name1, const std::wstring & name2, size_t len);
bool IsLastTag(const wchar_t * name);
bool IsLastTag(const std::wstring & name);
bool IsTagSafe(const wchar_t * tag);
bool IsTagSafe(const std::wstring & tag);
int CheckOrphan(const wchar_t * str, const wchar_t * end, const std::wstring & orphan_str);
bool CheckOrphan(const wchar_t * str, const wchar_t * end, const std::vector<std::wstring> & orphans);
bool CheckOrphan(const wchar_t * str, const wchar_t * end);
bool IsWhite(int c);
void SkipWhite();
void SkipWhiteLines();
void SkipWhiteWithFirstNewLine();
void SkipWhiteLines(const wchar_t * & str, const wchar_t * end);
bool IsClosingTagForLastItem();
size_t OpeningCommentaryTagMarkSize();
void SkipAndCheckClosingTag();
void PopStack();
bool PushStack();
void CheckNewLine();
void CheckStackPrintRest();
void AddForgottenTags();
void CheckClosingTags();
void ReadNormalText();
bool PrintRest();
bool PrintOpeningItem();
void ReadItemName();
void ReadItemAttrName();
void ReadItemAttrValue(bool has_quote);
bool ReadItemAttr();
bool CheckItemAttr();
void PrintItemAttr();
void ReadItemClosing();
void ReadItemSpecial();
void ReadItemOpening();
bool ReadItem();
void ReadLoop();
void Read();
void CheckChar(wchar_t c);
void CheckLineWrap();
bool HasSemiloconAround(const wchar_t * str, const wchar_t * end);
void PutNormalNonWhite(const wchar_t * & str, const wchar_t * end);
void PutNormalWhite(const wchar_t * & str, const wchar_t * end);
void PutLastTagWithClosingTag();
void PutTextBetweenLastTagWithClosingTag();
void PutTabs(size_t len);
void PutNonBreakingSpace();
void PutNewLine();
void CalcOrphansMaxLen(Orphans & orphans);
const wchar_t * pchar;
Item empty;
Item * pstack; // stack pointer
size_t stack_len; // length of the stack
wchar_t * buffer; // buffer used when printing
std::wstring * out_string;
bool last_new_line;
size_t break_after; // insert a space into long words after 'break_after' characters
size_t wrap_line; // insert a new line character into long lines
bool trim_white; // trimming white characters
size_t tab_size;
OrphanMode orphan_mode;
std::wstring attr_name;
std::vector<std::wstring> attr_value;
std::wstring attr_value_temp;
std::wstring attr_value_lower;
bool attr_has_value;
std::wstring lang_code_lower;
size_t line_len; //length of the current line (without first spaces which create the html tree)
bool safe_mode; // skipping some unsafe tags
Orphans orphans_temp;
};
} // namespace Winix
#endif

View File

@@ -1,15 +1,46 @@
/* /*
* This file is a part of CMSLU -- Content Management System like Unix * This file is a part of Winix
* and is not publicly distributed * and is distributed under the 2-Clause BSD licence.
* * Author: Tomasz Sowa <t.sowa@ttmath.org>
* Copyright (c) 2008, Tomasz Sowa */
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/ */
#include "httpsimpleparser.h" #include "httpsimpleparser.h"
namespace Winix
{
void HttpSimpleParser::ToLower(std::string & s) void HttpSimpleParser::ToLower(std::string & s)
{ {
std::string::iterator i; std::string::iterator i;
@@ -101,12 +132,16 @@ void HttpSimpleParser::CheckSpecialChar()
int c2 = GetChar(); int c2 = GetChar();
if( c1==-1 || c2==-1 ) if( c1==-1 || c2==-1 )
{
last_c = -1; last_c = -1;
}
else
{
c1 = ParseHalfHex(c1);
c2 = ParseHalfHex(c2);
c1 = ParseHalfHex(c1); last_c = (c1 << 4) + c2;
c2 = ParseHalfHex(c2); }
last_c = (c1 << 4) + c2;
} }
else else
if( last_c == '+' ) if( last_c == '+' )
@@ -219,13 +254,5 @@ void HttpSimpleParser::Parse()
} // namespace Winix

View File

@@ -1,19 +1,47 @@
/* /*
* This file is a part of CMSLU -- Content Management System like Unix * This file is a part of Winix
* and is not publicly distributed * and is distributed under the 2-Clause BSD licence.
* * Author: Tomasz Sowa <t.sowa@ttmath.org>
* Copyright (c) 2008, Tomasz Sowa */
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/ */
#ifndef headerfilehttpsimpleparser #ifndef headerfile_winix_core_httpsimpleparser
#define headerfilehttpsimpleparser #define headerfile_winix_core_httpsimpleparser
#include <string> #include <string>
namespace Winix
{
class HttpSimpleParser class HttpSimpleParser
{ {
@@ -46,7 +74,7 @@ protected:
void TrimWhiteChars(std::string & s); void TrimWhiteChars(std::string & s);
void CheckSpecialChar(); void CheckSpecialChar();
void Parse();
public: public:
@@ -60,15 +88,12 @@ public:
skip_white_chars = false; skip_white_chars = false;
recognize_special_chars = true; recognize_special_chars = true;
} }
void Parse();
}; };
} // namespace Winix
#endif #endif

634
core/image.cpp Executable file
View File

@@ -0,0 +1,634 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2010-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <ctime>
#include "image.h"
#include "utf8/utf8.h"
#include "log.h"
#include "system.h"
#include "plugin.h"
#include "lock.h"
namespace Winix
{
void Image::SetDb(Db * pdb)
{
db = pdb;
}
void Image::SetConfig(Config * pconfig)
{
config = pconfig;
}
void Image::SetSystem(System * psystem)
{
system = psystem;
}
// first thread (objects locked)
Image::Scale Image::GetImageScale(long dir_id)
{
Scale scale;
Mount * m = system->mounts.CalcMount(dir_id);
scale.cx = config->image_cx;
scale.cy = config->image_cy;
scale.aspect_mode = config->image_mode;
scale.quality = config->image_quality;
// reading width and height from the mount point (if exists)
int index = system->mounts.MountParImageSize();
if( m && m->param[index].defined && m->param[index].arg.size() == 2 )
{
scale.cx = Tol(m->param[index].arg[0]);
scale.cy = Tol(m->param[index].arg[1]);
}
// reading image mode from the mount point (if exists)
index = system->mounts.MountParImageMode();
if( m && m->param[index].defined && m->param[index].arg.size() == 1 )
scale.aspect_mode = Toi(m->param[index].arg[0]);
// reading image quality from the mount point (if exists)
index = system->mounts.MountParImageQuality();
if( m && m->param[index].defined && m->param[index].arg.size() == 1 )
scale.quality = Toi(m->param[index].arg[0]);
return scale;
}
// first thread (objects locked)
Image::Scale Image::GetThumbScale(long dir_id)
{
Scale scale;
Mount * m = system->mounts.CalcMount(dir_id);
scale.cx = config->thumb_cx;
scale.cy = config->thumb_cy;
scale.aspect_mode = config->thumb_mode;
scale.quality = config->thumb_quality;
// reading width and height from the mount point (if exists)
int index = system->mounts.MountParThumbSize();
if( m && m->param[index].defined && m->param[index].arg.size() == 2 )
{
scale.cx = Tol(m->param[index].arg[0]);
scale.cy = Tol(m->param[index].arg[1]);
}
// reading thumb mode from the mount point (if exists)
index = system->mounts.MountParThumbMode();
if( m && m->param[index].defined && m->param[index].arg.size() == 1 )
scale.aspect_mode = Toi(m->param[index].arg[0]);
// reading image quality from the mount point (if exists)
index = system->mounts.MountParThumbQuality();
if( m && m->param[index].defined && m->param[index].arg.size() == 1 )
scale.quality = Toi(m->param[index].arg[0]);
return scale;
}
// first thread (objects locked)
void Image::Resize(long file_id, size_t cx, size_t cy, int aspect_mode, int quality)
{
item_temp.type = WINIX_IMAGE_TYPE_RESIZE;
item_temp.file_id = file_id;
item_temp.cx = cx;
item_temp.cy = cy;
item_temp.aspect_mode = aspect_mode;
item_temp.quality = quality;
CheckParam(item_temp);
image_tab.insert(image_tab.end(), item_temp);
WakeUpThread();
}
// first thread (objects locked)
void Image::CreateThumb(long file_id, size_t thumb_cx, size_t thumb_cy, int aspect_mode, int quality)
{
item_temp.type = WINIX_IMAGE_TYPE_CREATE_THUMB;
item_temp.file_id = file_id;
item_temp.thumb_cx = thumb_cx;
item_temp.thumb_cy = thumb_cy;
item_temp.aspect_mode = aspect_mode;
item_temp.quality = quality;
CheckParam(item_temp);
image_tab.insert(image_tab.end(), item_temp);
WakeUpThread();
}
// first thread (objects locked)
void Image::Crop(long file_id, size_t xoffset, size_t yoffset, size_t cx, size_t cy, int quality)
{
item_temp.type = WINIX_IMAGE_TYPE_CROP;
item_temp.file_id = file_id;
item_temp.xoffset = xoffset;
item_temp.yoffset = yoffset;
item_temp.cx = cx;
item_temp.cy = cy;
item_temp.quality = quality;
CheckParam(item_temp);
image_tab.insert(image_tab.end(), item_temp);
WakeUpThread();
}
// first thread (objects locked)
void Image::CropThumb(long file_id, size_t xoffset, size_t yoffset, size_t cx, size_t cy, int quality)
{
item_temp.type = WINIX_IMAGE_TYPE_CROP_THUMB;
item_temp.file_id = file_id;
item_temp.xoffset = xoffset;
item_temp.yoffset = yoffset;
item_temp.cx = cx;
item_temp.cy = cy;
item_temp.quality = quality;
CheckParam(item_temp);
image_tab.insert(image_tab.end(), item_temp);
WakeUpThread();
}
// first thread (objects locked)
void Image::CropNewThumb(long file_id, size_t xoffset, size_t yoffset, size_t cx, size_t cy,
size_t thumb_cx, size_t thumb_cy, int aspect_mode, int quality)
{
item_temp.type = WINIX_IMAGE_TYPE_CREATE_CROP_NEW_THUMB;
item_temp.file_id = file_id;
item_temp.xoffset = xoffset;
item_temp.yoffset = yoffset;
item_temp.cx = cx;
item_temp.cy = cy;
item_temp.thumb_cx = thumb_cx;
item_temp.thumb_cy = thumb_cy;
item_temp.aspect_mode = aspect_mode;
item_temp.quality = quality;
CheckParam(item_temp);
image_tab.insert(image_tab.end(), item_temp);
WakeUpThread();
}
void Image::CheckParam(ImageItem & item)
{
SetMinMax(item.aspect_mode, 1, 7);
SetMinMax(item.quality, 0, 100);
SetMinMax(item.cx, 1, 30000);
SetMinMax(item.cy, 1, 30000);
SetMinMax(item.thumb_cx, 1, 30000);
SetMinMax(item.thumb_cy, 1, 30000);
SetMinMax(item.xoffset, 0, 30000);
SetMinMax(item.yoffset, 0, 30000);
}
// second thread (objects locked)
bool Image::SignalReceived()
{
return !image_tab.empty();
}
// second thread (objects not locked)
void Image::Do()
{
ImageTab::iterator i;
bool end;
Lock();
i = image_tab.begin();
Unlock();
do
{
class Lock lock_object(synchro);
if( i != image_tab.end() )
{
item_work = *i;
image_tab.erase(i++);
end = false;
}
else
{
end = true;
}
lock_object.Unlock();
if( !end )
CreateImage();
}
while( !end && !IsExitSignal() );
}
void Image::Add(const std::wstring & in, TextStream<std::string> & out)
{
PT::WideToUTF8(in, add_tempa);
out << add_tempa;
}
void Image::EscapePath(const std::string & path, TextStream<std::string> & out, bool clear_stream)
{
if( clear_stream )
out.Clear();
out << '"';
for(size_t i=0 ; i<path.size() ; ++i)
{
if( path[i] == '"' )
out << '\\';
if( path[i] != 0 )
out << path[i];
}
out << '\"';
}
/*
from: http://www.imagemagick.org/script/command-line-processing.php#geometry
scale% Height and width both scaled by specified percentage.
scale-x%xscale-y% Height and width individually scaled by specified percentages. (Only one % symbol needed.)
width Width given, height automagically selected to preserve aspect ratio.
xheight Height given, width automagically selected to preserve aspect ratio.
widthxheight Maximum values of height and width given, aspect ratio preserved.
widthxheight^ Minimum values of width and height given, aspect ratio preserved.
widthxheight! Width and height emphatically given, original aspect ratio ignored.
widthxheight> Change as per widthxheight but only if an image dimension exceeds a specified dimension.
widthxheight< Change dimensions only if both image dimensions exceed specified dimensions.
*/
void Image::SelectAspect(size_t cx, size_t cy)
{
switch( item_work.aspect_mode )
{
case WINIX_IMAGE_MODE_1:
command << cx;
break;
case WINIX_IMAGE_MODE_3:
command << cx << "x" << cy;
break;
case WINIX_IMAGE_MODE_4:
command << '"' << cx << "x" << cy << "^\"";
break;
case WINIX_IMAGE_MODE_5:
command << '"' << cx << "x" << cy << "!\"";
break;
case WINIX_IMAGE_MODE_6:
command << '"' << cx << "x" << cy << ">\"";
break;
case WINIX_IMAGE_MODE_7:
command << '"' << cx << "x" << cy << "<\"";
break;
case WINIX_IMAGE_MODE_2:
default:
command << "x" << cy;
break;
}
}
// second thread (objects locked)
bool Image::CreateInputFileName()
{
bool thumb = (item_work.type == WINIX_IMAGE_TYPE_CROP_THUMB);
if( thumb && !file_work.has_thumb )
{
log << log1 << "Image: file id: " << file_work.id << ", url: " << file_work.url
<< " doesn't have a thumbnail yet (skipping)" << logend;
return false;
}
if( system->MakeFilePath(file_work, src_path, thumb) )
{
PT::WideToUTF8(src_path, input_file_name);
return true;
}
else
{
log << log1 << "Image: cannot create a source path" << logend;
return false;
}
}
// second thread (objects locked)
void Image::CreateTmpFileName()
{
stream_tmp_path.Clear();
stream_tmp_path << config->upload_dir << L"/tmp/image_" << std::time(0);
PT::WideToUTF8(stream_tmp_path.Str(), tmp_file_name);
}
// second thread (objects are not locked)
bool Image::CreateCommand()
{
class Lock lock_object(synchro);
iq.SetAll(true, false);
iq.WhereId(item_work.file_id);
// the file could have been changed especially when there is a long queue of files
if( db->GetItem(file_work, iq) != WINIX_ERR_OK )
return false;
if( !CreateInputFileName() )
return false;
command.Clear();
Add(config->convert_cmd, command);
command << " ";
EscapePath(input_file_name, command, false);
command << " -quiet -quality " << item_work.quality;
if( item_work.type == WINIX_IMAGE_TYPE_RESIZE )
{
command << " -resize ";
SelectAspect(item_work.cx, item_work.cy);
}
else
if( item_work.type == WINIX_IMAGE_TYPE_CREATE_THUMB )
{
command << " -strip -thumbnail ";
SelectAspect(item_work.thumb_cx, item_work.thumb_cy);
}
else
if( item_work.type == WINIX_IMAGE_TYPE_CROP )
{
command << " -crop " << item_work.cx << "x" << item_work.cy
<< "+" << item_work.xoffset << "+" << item_work.yoffset << " +repage ";
}
else
if( item_work.type == WINIX_IMAGE_TYPE_CROP_THUMB )
{
command << " -strip -crop " << item_work.cx << "x" << item_work.cy
<< "+" << item_work.xoffset << "+" << item_work.yoffset
<< " +repage ";
}
else
if( item_work.type == WINIX_IMAGE_TYPE_CREATE_CROP_NEW_THUMB )
{
command << " -strip -crop " << item_work.cx << "x" << item_work.cy
<< "+" << item_work.xoffset << "+" << item_work.yoffset
<< " +repage -thumbnail ";
SelectAspect(item_work.thumb_cx, item_work.thumb_cy);
}
CreateTmpFileName();
command << " ";
EscapePath(tmp_file_name, command, false);
log << log4 << "Image: running: " << command.Str() << logend;
return true;
}
// second thread (objects are locked)
void Image::ImageSavedCorrectly()
{
if( item_work.type == WINIX_IMAGE_TYPE_CREATE_THUMB )
{
if( !file_work.has_thumb )
{
file_work.has_thumb = true;
db->EditHasThumbById(true, file_work.id);
}
log << log3 << "Image: generated a thumbnail: " << dst_path << logend;
plugin.Call((Session*)0, WINIX_CREATED_THUMB, &file_work);
}
else
if( item_work.type == WINIX_IMAGE_TYPE_RESIZE )
{
log << log3 << "Image: image resized: " << dst_path << logend;
plugin.Call((Session*)0, WINIX_IMAGE_RESIZED, &file_work);
}
else
if( item_work.type == WINIX_IMAGE_TYPE_CROP )
{
log << log3 << "Image: image cropped: " << dst_path << logend;
// !! IMPROVE ME add a correct message
//plugin.Call((Session*)0, WINIX_IMAGE_RESIZED, &file_work);
}
else
if( item_work.type == WINIX_IMAGE_TYPE_CROP_THUMB )
{
log << log3 << "Image: image thumbnail cropped: " << dst_path << logend;
// !! IMPROVE ME add a correct message
//plugin.Call((Session*)0, WINIX_IMAGE_RESIZED, &file_work);
}
else
if( item_work.type == WINIX_IMAGE_TYPE_CREATE_CROP_NEW_THUMB )
{
log << log3 << "Image: a new thumbnail from an original image was cropped: " << dst_path << logend;
// !! IMPROVE ME add a correct message
//plugin.Call((Session*)0, WINIX_IMAGE_RESIZED, &file_work);
}
}
// second thread (objects are not locked)
void Image::SaveImage()
{
class Lock lock_object(synchro);
// the file could have been changed especially when creating the image lasted too long
iq.SetAll(true, false);
iq.WhereId(item_work.file_id);
if( db->GetItem(file_work, iq) == WINIX_ERR_OK )
{
bool thumb = (item_work.type == WINIX_IMAGE_TYPE_CREATE_THUMB ||
item_work.type == WINIX_IMAGE_TYPE_CROP_THUMB ||
item_work.type == WINIX_IMAGE_TYPE_CREATE_CROP_NEW_THUMB );
if( system->MakeFilePath(file_work, dst_path, thumb, true, config->upload_dirs_chmod, config->upload_group_int) )
{
if( RenameFile(stream_tmp_path.Str(), dst_path) )
{
// it doesn't matter for us if there is an error when chmod/chown on a file
// the admin (root) will correct it
std::string dst_patha; // IMPROVE ME temporary -- in the futere there'll be SetPriv() with std::wstring
PT::WideToUTF8(dst_path, dst_patha);
SetPriv(dst_patha, config->upload_files_chmod, config->upload_group_int);
ImageSavedCorrectly();
}
else
{
log << log1 << "Image: cannot move a temporary file: " << stream_tmp_path.Str()
<< ", to: " << dst_path << logend;
Winix::RemoveFile(stream_tmp_path.Str());
}
}
else
{
log << log1 << "Image: cannot create a destination path" << logend;
}
}
}
// second thread (objects are not locked)
void Image::CreateImage()
{
if( CreateCommand() )
{
int res = std::system(command.CStr());
if( res == 0 )
{
SaveImage();
}
else
{
class Lock lock_object(synchro);
log << log3 << "Image: some problems with creating an image"
<< ", 'convert' process returned: " << res << logend;
}
}
}
// second thread (objects are not locked)
// !! there is a problem with GIF files
// Bus error (core dumped)
/*
#include "wand/MagickWand.h"
// compiler options:
// include: -I/usr/local/include/ImageMagick
// link with: `MagickWand-config --ldflags --libs`
void Image::CreateThumbnail()
{
PT::WideToUTF8(item_work.source, sourcea);
PT::WideToUTF8(item_work.dst, dsta);
MagickWandGenesis();
MagickWand * wand = NewMagickWand();
if( MagickReadImage(wand, sourcea.c_str()) )
{
MagickThumbnailImage(wand, item_work.cx, item_work.cy);
if( MagickWriteImage(wand, dsta.c_str()) )
{
Lock();
log << log3 << "Image: created a thumbnail: " << dsta << logend;
Unlock();
}
}
DestroyMagickWand(wand);
MagickWandTerminus();
}
*/
} // namespace Winix

215
core/image.h Executable file
View File

@@ -0,0 +1,215 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2010-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_image
#define headerfile_winix_core_image
#include <string>
#include <list>
#include "basethread.h"
#include "textstream.h"
#include "db/db.h"
#include "core/item.h"
#include "core/config.h"
namespace Winix
{
class System;
// aspect modes:
// Width given, height automagically selected to preserve aspect ratio.
#define WINIX_IMAGE_MODE_1 1
// Height given, width automagically selected to preserve aspect ratio.
#define WINIX_IMAGE_MODE_2 2
// Maximum values of height and width given, aspect ratio preserved.
#define WINIX_IMAGE_MODE_3 3
// Minimum values of width and height given, aspect ratio preserved.
#define WINIX_IMAGE_MODE_4 4
// Width and height emphatically given, original aspect ratio ignored.
#define WINIX_IMAGE_MODE_5 5
// Change as per widthxheight but only if an image dimension exceeds a specified dimension.
#define WINIX_IMAGE_MODE_6 6
// Change dimensions only if both image dimensions are less than specified dimensions.
#define WINIX_IMAGE_MODE_7 7
// resizing
#define WINIX_IMAGE_TYPE_RESIZE 1
// generating a thumbnail
#define WINIX_IMAGE_TYPE_CREATE_THUMB 2
// cropping an image
#define WINIX_IMAGE_TYPE_CROP 3
// cropping an thumbnail
#define WINIX_IMAGE_TYPE_CROP_THUMB 4
// creating by cropping a new thumbnail (from an original image)
#define WINIX_IMAGE_TYPE_CREATE_CROP_NEW_THUMB 5
/*
*/
class Image : public BaseThread
{
public:
struct Scale
{
size_t cx;
size_t cy;
int aspect_mode;
int quality;
Scale()
{
cx = cy = 1;
aspect_mode = 2;
quality = 100;
};
};
void SetDb(Db * pdb);
void SetConfig(Config * pconfig);
void SetSystem(System * psystem);
// returning scale info for a directory
Scale GetImageScale(long dir_id);
// returning scale info (for thumbnails) for a directory
Scale GetThumbScale(long dir_id);
void Resize(long file_id, size_t cx, size_t cy, int aspect_mode, int quality);
// creating a new thumbnail from an original image
void CreateThumb(long file_id, size_t thumb_cx, size_t thumb_cy, int aspect_mode, int quality);
// cropping an image (the thumbnail is not changed)
void Crop(long file_id, size_t xoffset, size_t yoffset, size_t cx, size_t cy, int quality);
// cropping an existing thumbnail
void CropThumb(long file_id, size_t xoffset, size_t yoffset, size_t cx, size_t cy, int quality);
// creating and cropping a new thumbnail (from an original image)
void CropNewThumb(long file_id, size_t xoffset, size_t yoffset, size_t cx, size_t cy,
size_t thumb_cx, size_t thumb_cy, int aspect_mode, int quality);
private:
Db * db;
Config * config;
System * system;
struct ImageItem
{
int type; // WINIX_IMAGE_TYPE_*
long file_id;
size_t cx;
size_t cy;
size_t xoffset; // xoffset and yoffset are used when cropping
size_t yoffset;
size_t thumb_cx;
size_t thumb_cy;
int aspect_mode;
int quality;
};
template<typename int_type>
void SetMinMax(int_type & var, int var_min, int var_max)
{
if( static_cast<int>(var) < var_min )
var = var_min;
if( static_cast<int>(var) > var_max )
var = var_max;
}
// queue of thumbnails to create
typedef std::list<ImageItem> ImageTab;
ImageTab image_tab;
ImageItem item_temp;
// only for second thread
ImageItem item_work;
std::wstring src_path, dst_path;
TextStream<std::string> command;
TextStream<std::wstring> stream_tmp_path;
DbItemQuery iq;
std::string add_tempa;
std::string input_file_name;
std::string tmp_file_name;
Item file_work;
virtual bool SignalReceived();
virtual void Do();
bool CreateCommand();
bool CreateInputFileName();
void CreateTmpFileName();
void SaveImage();
void CreateImage();
void SelectAspect(size_t cx, size_t cy);
void EscapePath(const std::string & path, TextStream<std::string> & out, bool clear_stream = true);
void CheckParam(ImageItem & item);
void Add(const std::wstring & in, TextStream<std::string> & out);
void ImageSavedCorrectly();
};
} // namespace Winix
#endif

185
core/ipban.h Normal file
View File

@@ -0,0 +1,185 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2012-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_ipban
#define headerfile_winix_core_ipban
#include <ctime>
namespace Winix
{
// telling if the IPBan record is active
// we have two records: active and non active
// non active records is something like a history
// it is used to remember the last ban level
// so based on this in the future a next greater ban can be calculated
#define WINIX_IPBAN_FLAG_ACTIVE 1
// current ban level
// (if one of these flag is set and the record is active then it means the IP is banned at the moment)
// level 1: banned for short time
// level 2: can be set after level 1 has expired and the attacker still have not given up
// banned for some longer time in level 1
// level 3: can be set after level 2
// banned for much more time
#define WINIX_IPBAN_FLAG_BAN_LEVEL1 2
#define WINIX_IPBAN_FLAG_BAN_LEVEL2 4
#define WINIX_IPBAN_FLAG_BAN_LEVEL3 8
/*
struct defining some restrictions to an IP address
*/
struct IPBan
{
// at the moment only IPv4 are supported
int ip;
// one or more flags from WINIX_IPBAN_FLAG_*
int flags;
// when this record was last used
time_t last_used;
// when the restrictions (ban) should be removed
// valid only if some of WINIX_IPBAN_FLAG_BAN_LEVELX flags are set
// actually we do not remove the record but unsets WINIX_IPBAN_FLAG_ACTIVE flag
// so in the future we can check whether we need to change
// the ban level to a greater value
time_t expires;
// how many incorrect login attempts there are
unsigned int incorrect_login_events;
// in the future there can be more *_events fields
bool HasFlag(int flag) const
{
return (flags & flag) != 0;
}
void SetFlag(int flag)
{
flags = flags | flag;
}
void ClearFlag(int flag)
{
flags = flags & (~flag);
}
bool IsIPBanned() const
{
if( !HasFlag(WINIX_IPBAN_FLAG_ACTIVE) )
return false;
return HasFlag(WINIX_IPBAN_FLAG_BAN_LEVEL1) ||
HasFlag(WINIX_IPBAN_FLAG_BAN_LEVEL2) ||
HasFlag(WINIX_IPBAN_FLAG_BAN_LEVEL3);
}
void AddNextBanLevel(time_t level1_expires, time_t level2_expires, time_t level3_expires)
{
if( HasFlag(WINIX_IPBAN_FLAG_BAN_LEVEL3) )
{
expires = level3_expires;
return;
}
else
if( HasFlag(WINIX_IPBAN_FLAG_BAN_LEVEL2) )
{
SetFlag(WINIX_IPBAN_FLAG_BAN_LEVEL3);
expires = level3_expires;
return;
}
else
if( HasFlag(WINIX_IPBAN_FLAG_BAN_LEVEL1) )
{
SetFlag(WINIX_IPBAN_FLAG_BAN_LEVEL2);
expires = level2_expires;
return;
}
else
{
SetFlag(WINIX_IPBAN_FLAG_BAN_LEVEL1);
expires = level1_expires;
}
}
IPBan()
{
Clear();
}
void Clear()
{
ip = 0;
flags = 0;
last_used = 0;
expires = 0;
incorrect_login_events = 0;
}
void ClearAfterRemovingBan()
{
ClearFlag(WINIX_IPBAN_FLAG_ACTIVE);
incorrect_login_events = 0;
expires = 0;
}
};
} // namespace Winix
#endif

253
core/ipbancontainer.cpp Normal file
View File

@@ -0,0 +1,253 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2012-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <algorithm>
#include "ipbancontainer.h"
#include "log.h"
#include "date/date.h"
namespace Winix
{
IPBanContainer::IPBanContainer()
{
is_ipban_tab_sorted = true; // an empty list is sorted
soft_max_size = 100;
max_size = 110;
}
void IPBanContainer::SetMaxSize(size_t soft_size, size_t size)
{
soft_max_size = soft_size;
max_size = size;
if( max_size < soft_max_size )
max_size = soft_max_size + 1;
ipban_tab.reserve(max_size);
sort_helper_tab.reserve(max_size);
}
// returning a reference to the added (or existed) record
IPBan & IPBanContainer::AddIP(int ip)
{
IPBan * old_ip_ban = FindIP(ip);
if( !old_ip_ban )
{
IPBan ip_ban;
ip_ban.ip = ip;
if( ipban_tab.size() >= max_size )
RemoveOldRecords();
ipban_tab.push_back(ip_ban);
is_ipban_tab_sorted = false;
return ipban_tab.back();
}
else
{
return *old_ip_ban;
}
}
void IPBanContainer::RemoveIP(int ip)
{
IPBan * ipban = FindIP(ip);
if( ipban )
{
size_t index = ipban - &ipban_tab[0];
ipban_tab.erase(ipban_tab.begin() + index);
}
}
bool IPBanContainer::IsSorted()
{
return is_ipban_tab_sorted;
}
void IPBanContainer::Clear()
{
ipban_tab.clear();
is_ipban_tab_sorted = true;
}
// we need to remove some old records for the size of the container
// to be less or equal to soft_max_size
void IPBanContainer::RemoveOldRecords()
{
size_t to_remove = 0;
if( ipban_tab.size() >= soft_max_size )
to_remove = ipban_tab.size() - soft_max_size;
if( to_remove > 0 )
{
sort_helper_tab.resize(ipban_tab.size());
for(size_t i=0 ; i<ipban_tab.size() ; ++i)
sort_helper_tab[i] = i;
std::sort(sort_helper_tab.begin(), sort_helper_tab.end(), SortByLastUsedHelper(this));
sort_helper_tab.resize(to_remove);
std::sort(sort_helper_tab.begin(), sort_helper_tab.end());
while( to_remove-- > 0 )
ipban_tab.erase(ipban_tab.begin() + sort_helper_tab[to_remove]);
}
}
// for debug purposes
void IPBanContainer::PrintTab()
{
log << log4 << "ipban_tab (size: " << ipban_tab.size() << ")" << logend;
for(size_t i=0 ; i<ipban_tab.size() ; ++i)
{
log << log4 << i << ": ip: " << ipban_tab[i].ip << ", flags: " << ipban_tab[i].flags << ", last_used: ";
PT::Date date(ipban_tab[i].last_used);
log << date << ", expires: ";
date = ipban_tab[i].expires;
log << date << logend;
}
}
// for debug purposes
void IPBanContainer::PrintTab2()
{
log << log4 << "sort_helper_tab (size: " << sort_helper_tab.size() << ")" << logend;
for(size_t i=0 ; i<sort_helper_tab.size() ; ++i)
{
IPBan & ipban = ipban_tab[sort_helper_tab[i]];
log << log4 << i << ": ip: " << ipban.ip << ", flags: " << ipban.flags << ", last_used: ";
PT::Date date(ipban.last_used);
log << date << ", expires: ";
date = ipban.expires;
log << date << logend;
}
}
bool IPBanContainer::SortByLastUsedHelper::operator()(size_t index1, size_t index2)
{
if( index1 < container->ipban_tab.size() &&
index2 < container->ipban_tab.size() )
{
IPBan & ip1 = container->ipban_tab[index1];
IPBan & ip2 = container->ipban_tab[index2];
// prefer to select records which do not have WINIX_IPBAN_FLAG_ACTIVE
if( ip1.HasFlag(WINIX_IPBAN_FLAG_ACTIVE) !=
ip2.HasFlag(WINIX_IPBAN_FLAG_ACTIVE) )
{
return ip2.HasFlag(WINIX_IPBAN_FLAG_ACTIVE);
}
return ip1.last_used < ip2.last_used;
}
return false;
}
IPBan * IPBanContainer::FindIP(int ip)
{
// !! IMPROVE ME add binary search if is_ipban_tab_sorted is true
for(size_t i=0 ; i<ipban_tab.size() ; ++i)
{
if( ipban_tab[i].ip == ip )
{
return &ipban_tab[i];
}
}
return 0;
}
IPBan & IPBanContainer::GetIPBan(size_t index)
{
return ipban_tab[index];
}
void IPBanContainer::Sort()
{
std::sort(ipban_tab.begin(), ipban_tab.end(), SortIPBansFunction);
is_ipban_tab_sorted = true;
}
size_t IPBanContainer::Size()
{
return ipban_tab.size();
}
bool IPBanContainer::SortIPBansFunction(const IPBan & ip1, const IPBan & ip2)
{
return ip1.ip < ip2.ip;
}
} // namespace Winix

90
core/ipbancontainer.h Normal file
View File

@@ -0,0 +1,90 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2012-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_ipbancontainer
#define headerfile_winix_core_ipbancontainer
#include <vector>
#include "ipban.h"
namespace Winix
{
class IPBanContainer
{
public:
IPBanContainer();
IPBan & AddIP(int ip);
IPBan * FindIP(int ip);
void Sort();
size_t Size();
IPBan & GetIPBan(size_t index);
void SetMaxSize(size_t soft_size, size_t size);
void RemoveIP(int ip);
void Clear();
bool IsSorted();
private:
std::vector<IPBan> ipban_tab;
bool is_ipban_tab_sorted;
size_t soft_max_size, max_size;
std::vector<size_t> sort_helper_tab;
static bool SortIPBansFunction(const IPBan & ip1, const IPBan & ip2);
void RemoveOldRecords();
void PrintTab();
void PrintTab2();
struct SortByLastUsedHelper
{
IPBanContainer * container;
SortByLastUsedHelper(IPBanContainer * c) : container(c) {}
bool operator()(size_t index1, size_t index2);
};
};
} // namespace Winix
#endif

115
core/item.cpp Executable file
View File

@@ -0,0 +1,115 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2010-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "item.h"
#include "misc.h"
#include "crypt.h"
namespace Winix
{
Item::Item()
{
Clear();
}
// !! IMPROVE ME
// now we have Request::start_time and Request::start_date
// we can somehow get the current time from the request
// may setting the date should be completetly removed from here?
void Item::SetDateToNow()
{
date_creation = std::time(0);
date_modification = date_creation;
}
void Item::SetDateModifyToNow()
{
date_modification = std::time(0);
}
void Item::Clear()
{
id = -1;
user_id = -1;
group_id = -1;
privileges = 0;
modification_user_id = -1;
guest_name.clear();
subject.clear();
content.clear();
modify_index = 0;
url.clear();
content_type = ct_formatted_text;
type = none;
parent_id = -1;
link_to.clear();
link_redirect = false;
content_id = -1;
ref = 1;
file_path.clear();
file_fs = -1;
file_type = WINIX_ITEM_FILETYPE_NONE;
hash.clear();
hash_type = WINIX_CRYPT_HASH_NONE;
file_size = 0;
has_thumb = false;
html_template.clear();
sort_index = 0;
meta.Clear();
ameta.Clear();
SetDateToNow();
}
} // namespace Winix

View File

@@ -1,94 +1,152 @@
/* /*
* This file is a part of CMSLU -- Content Management System like Unix * This file is a part of Winix
* and is not publicly distributed * and is distributed under the 2-Clause BSD licence.
* * Author: Tomasz Sowa <t.sowa@ttmath.org>
* Copyright (c) 2008, Tomasz Sowa */
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/ */
#ifndef headerfileitem #ifndef headerfile_winix_core_item
#define headerfileitem #define headerfile_winix_core_item
#include <string> #include <string>
#include "space/space.h"
#include "date/date.h"
namespace Winix
{
#define WINIX_ITEM_FILETYPE_NONE 0
#define WINIX_ITEM_FILETYPE_IMAGE 1
#define WINIX_ITEM_FILETYPE_DOCUMENT 2
#define WINIX_ITEM_FILETYPE_VIDEO 3
#define WINIX_ITEM_FILETYPE_UNKNOWN 10
struct Item struct Item
{ {
long id; long id;
long parent_id;
long user_id; long user_id;
long group_id; long group_id;
int privileges; std::wstring guest_name; // used as a user name when user_id is equal -1
long modification_user_id; // who has modified the item last (not taken into account when checking permissions)
int privileges;
PT::Date date_creation;
PT::Date date_modification;
std::wstring subject;
std::wstring content;
std::wstring url;
int modify_index;
enum ContentType
{
ct_text = 0,
ct_formatted_text,
ct_html,
ct_bbcode,
ct_raw
};
ContentType content_type;
std::string subject;
std::string content; enum Type
std::string url; {
dir = 0,
file = 1,
symlink = 2,
none = 1000
};
int content_type; Type type;
enum Type // used when type is symlink or to a directory too (function 'default')
{ std::wstring link_to;
dir = 0, int link_redirect; // !! IMPROVE ME should it be 'bool'?
file = 1,
// static file (if exists)
std::wstring file_path; // relative file path
int file_fs; // file system type where the file was saved
int file_type; // file type (none, image, doc, etc)
bool has_thumb; // whether or not we have a thumbnail
std::wstring hash; // file hash (md4, md5, ...)
int hash_type; // hash type WINIX_CRYPT_HASH_* (see crypt.h)
size_t file_size; // size of the file
std::wstring html_template;
// sort index used when displaying a group of items
int sort_index;
none = 1000
// meta information
PT::Space meta;
PT::Space ameta;
// methods
Item();
void SetDateToNow();
void SetDateModifyToNow();
void Clear();
private:
// used by the database
long content_id; // content id in 'content' table
int ref; // content references
friend class Db;
friend struct DbItemColumns;
}; };
Type type;
//item_type; } // namespace Winix
long parent_id;
long default_item;
// used by the database
long content_id;
Item()
{
Clear();
}
void Clear()
{
id = -1;
user_id = -1;
group_id = -1;
privileges = 0;
subject.clear();
content.clear();
url.clear();
content_type = 0;
type = none;
parent_id = -1;
default_item = -1;
content_id = -1;
}
};

198
core/job.cpp Executable file
View File

@@ -0,0 +1,198 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2012-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "job.h"
#include "plugin.h"
#include "log.h"
namespace Winix
{
Job::Job()
{
jobs_queue_tab.resize(WINIX_JOBS_HOW_MANY_PRIORITIES);
}
void Job::CheckPriority(int & priority) const
{
if( priority < 0 )
priority = 0;
if( priority >= WINIX_JOBS_HOW_MANY_PRIORITIES )
priority = WINIX_JOBS_HOW_MANY_PRIORITIES - 1;
}
// first thread (objects locked)
void Job::Add(PT::Space & job, int priority)
{
CheckPriority(priority);
jobs_queue_tab[priority].push(job);
WakeUpThread();
}
size_t Job::Size(int priority) const
{
CheckPriority(priority);
return jobs_queue_tab[priority].size();
}
size_t Job::Size() const
{
size_t sum = 0;
for(size_t i=0 ; i<WINIX_JOBS_HOW_MANY_PRIORITIES ; ++i)
sum += Size(i);
return sum;
}
bool Job::Empty(int priority) const
{
CheckPriority(priority);
return jobs_queue_tab[priority].empty();
}
bool Job::Empty() const
{
for(size_t i=0 ; i<WINIX_JOBS_HOW_MANY_PRIORITIES ; ++i)
if( !Empty(i) )
return false;
return true;
}
/*
second thread
*/
// second thread (objects locked)
bool Job::SignalReceived()
{
return !Empty();
}
// second thread (objects not locked)
void Job::Do()
{
size_t i = WINIX_JOBS_HOW_MANY_PRIORITIES;
bool is_empty;
while( i-- > 0 && !IsExitSignal() )
{
do
{
Lock();
is_empty = Empty(i);
Unlock();
if( !is_empty )
DoQueue(jobs_queue_tab[i]);
}
while( !is_empty && !IsExitSignal() );
}
}
// second thread (objects not locked, jobs_queue is not empty)
void Job::DoQueue(JobsQueue & jobs_queue)
{
bool is_empty;
do
{
Lock();
// references will not be invalidated after insertion to jobs_queue
// (jobs_queue is std::queue and it uses std::deque by default)
PT::Space & job = jobs_queue.front();
Unlock();
DoJob(job);
Lock();
jobs_queue.pop();
is_empty = jobs_queue.empty();
Unlock();
}
while( !is_empty && !IsExitSignal() );
}
// second thread (objects not locked)
void Job::DoJob(PT::Space & job)
{
try
{
PluginRes res = plugin.Call((Session*)0, WINIX_JOB, &job);
if( res.res_true == 0 )
DoWinixJob(job);
}
catch(...)
{
}
}
// second thread (objects not locked)
void Job::DoWinixJob(PT::Space & job)
{
Lock();
//log << log1 << "standard winix job: " << job.Text(L"type") << logend;
Unlock();
}
} // namespace Winix

115
core/job.h Executable file
View File

@@ -0,0 +1,115 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2012-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_jobs
#define headerfile_winix_core_jobs
#include <vector>
#include <queue>
#include "basethread.h"
#include "space/space.h"
namespace Winix
{
#define WINIX_JOBS_HOW_MANY_PRIORITIES 32
class Job : public BaseThread
{
public:
Job();
/*
add a new job to the queue
priority: 0-31 (0 - the lowest priority, 31 - the highest priority)
*/
void Add(PT::Space & job, int priority = 0);
/*
queue size, and size of all jobs in any priority
*/
size_t Size(int priority) const;
size_t Size() const;
/*
true if specified queue is empty
or if all queues are empty
*/
bool Empty(int priority) const;
bool Empty() const;
private:
typedef std::queue<PT::Space> JobsQueue;
typedef std::vector<JobsQueue> JobsQueueTab;
JobsQueueTab jobs_queue_tab;
void CheckPriority(int & priority) const;
void SaveToFile();
void ReadFromFile();
/*
second thread
*/
// standard winix jobs
// Image image;
// sending emails
// etc.
bool SignalReceived();
void Do();
void DoQueue(JobsQueue & jobs_queue);
void DoJob(PT::Space & job);
void DoWinixJob(PT::Space & job);
};
} // namespace Winix
#endif

144
core/lastcontainer.cpp Executable file
View File

@@ -0,0 +1,144 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2009-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "lastcontainer.h"
#include "log.h"
#include "misc.h"
namespace Winix
{
LastItem::LastItem()
{
user_id = 0;
ip = 0;
session_id = 0;
}
bool LastItem::IsLoggedOut()
{
return end.year > 1970;
}
LastContainer::Iterator LastContainer::Begin()
{
return last_tab.begin();
}
LastContainer::Iterator LastContainer::End()
{
return last_tab.end();
}
LastContainer::Iterator LastContainer::FindNotLoggedOut(long user_id, long session_id)
{
LastTab::iterator i;
for(i=last_tab.begin() ; i!=last_tab.end() ; ++i)
{
if( i->user_id == user_id && i->session_id == session_id && !i->IsLoggedOut() )
return i;
}
return last_tab.end();
}
void LastContainer::UserLogin(long user_id, const std::wstring & name, unsigned int ip, long session_id)
{
LastTab::iterator i = FindNotLoggedOut(user_id, session_id);
if( i != last_tab.end() )
{
log << log1 << "LC: such a user and session_id exist, not added as a new one" << logend;
return;
}
if( last_tab.size() >= WINIX_LASTCONTAINER_TABLE_SIZE ) // last_tab has O(n) complexity
last_tab.erase(last_tab.begin());
LastItem li;
li.user_id = user_id;
li.name = name;
li.ip = ip;
li.session_id = session_id;
li.start = std::time(0);
last_tab.insert(last_tab.end(), li);
log << log2 << "LC: added user: " << name << " into the last table" << logend;
}
void LastContainer::UserLogout(long user_id, long session_id)
{
LastTab::iterator i = FindNotLoggedOut(user_id, session_id);
if( i != last_tab.end() )
{
i->end = std::time(0);
}
else
{
/*
!! IMPROVE ME
users read from the session file (at boot time)
are not added to LastContainer
*/
log << log4 << "LC: there is no such a user to log out: user_id: "
<< user_id << " ses_id: " << session_id << logend;
}
}
} // namespace Winix

112
core/lastcontainer.h Executable file
View File

@@ -0,0 +1,112 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2009-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_lastcontainer
#define headerfile_winix_core_lastcontainer
#include <string>
#include <list>
#include <cstring>
#include <ctime>
#include "date/date.h"
namespace Winix
{
// how many items we store in the 'last' function
#define WINIX_LASTCONTAINER_TABLE_SIZE 100
struct LastItem
{
long user_id;
// additional we store the whole string-name
// (you can delete a user from the database but we can still print the name)
std::wstring name;
// ip address
unsigned int ip;
// session id (used when logging out)
long session_id;
// start logging and end logging
PT::Date start;
PT::Date end;
LastItem();
bool IsLoggedOut();
};
class LastContainer
{
public:
typedef std::list<LastItem> LastTab;
typedef LastTab::iterator Iterator;
public:
Iterator Begin();
Iterator End();
void UserLogin(long user_id, const std::wstring & name, unsigned int ip, long session_id);
void UserLogout(long user_id, long session_id);
private:
LastTab last_tab;
Iterator FindNotLoggedOut(long user_id, long session_id);
};
} // namespace Winix
#endif

406
core/loadavg.cpp Executable file
View File

@@ -0,0 +1,406 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "loadavg.h"
#include "log.h"
namespace Winix
{
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;
}
} // namespace Winix

146
core/loadavg.h Executable file
View File

@@ -0,0 +1,146 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_loadavg
#define headerfile_winix_core_loadavg
#include <ctime>
namespace Winix
{
// 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;
};
} // namespace Winix
#endif

82
core/lock.cpp Executable file
View File

@@ -0,0 +1,82 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2012-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "lock.h"
namespace Winix
{
Lock::Lock()
{
synchro = 0;
}
Lock::Lock(Synchro * synchro_)
{
synchro = synchro_;
synchro->Lock();
}
Lock::Lock(Synchro & synchro_)
{
synchro = &synchro_;
synchro->Lock();
}
Lock::~Lock()
{
Unlock();
}
void Lock::Unlock()
{
if( synchro )
{
synchro->Unlock();
synchro = 0;
}
}
} // namespace Winix

71
core/lock.h Executable file
View File

@@ -0,0 +1,71 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2012-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_lock
#define headerfile_winix_core_lock
#include "synchro.h"
namespace Winix
{
class Lock
{
public:
Lock(Synchro * synchro_);
Lock(Synchro & synchro_);
~Lock();
void Unlock();
private:
Synchro * synchro;
Lock();
};
} // namespace Winix
#endif

View File

@@ -1,66 +1,240 @@
/* /*
* This file is a part of CMSLU -- Content Management System like Unix * This file is a part of Winix
* and is not publicly distributed * and is distributed under the 2-Clause BSD licence.
* * Author: Tomasz Sowa <t.sowa@ttmath.org>
* Copyright (c) 2008, Tomasz Sowa */
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/ */
#include "log.h" #include "log.h"
#include <ctime>
#include <string.h>
#include "utf8/utf8.h"
#include "timezones.h"
namespace Winix
{
Log::Log() Log::Log()
{ {
log_level = 3; log_level = 1;
current_level = 4; // nothing to log (call Init() first) current_level = 100; // nothing to log (call Init() first)
request = 0;
max_requests = 1;
lines = 0;
max_lines = 5000;
log_file_open = false;
time_zones = 0;
} }
void Log::Init(int log_l, const std::string & log_f, bool log_std) Log::~Log()
{ {
log_level = log_l; SaveLogAndClear();
log_file = log_f;
log_stdout = log_std;
} }
Log & Log::operator<<(const char * s) void Log::SetTimeZones(TimeZones * ptime_zones)
{ {
if( !s ) time_zones = ptime_zones;
}
int Log::LogLevel()
{
return log_level;
}
void Log::Init(int log_level_, bool save_each_line_, const std::string & log_file_, bool log_std, int log_max_requests)
{
log_level = log_level_;
log_file = log_file_;
log_stdout = log_std;
max_requests = log_max_requests;
save_each_line = save_each_line_;
// don't open the file here
// because it would be created with the root as an owner
}
void Log::OpenFile()
{
if( !log_file.empty() )
{
file.open( log_file.c_str(), std::ios_base::out | std::ios_base::app );
log_file_open = true;
}
}
void Log::PrintDate(const PT::Date & date, size_t time_zone_id)
{
if( time_zones )
{
TimeZone * tz = time_zones->GetZone(time_zone_id);
if( tz )
{
PT::Date local_date = tz->ToLocal(date);
log << local_date;
}
else
{
(*this) << date << " UTC"; // unknown time zone identifier
}
}
else
{
(*this) << date << " UTC"; // time_zones object was not set
}
}
Log & Log::operator<<(const void * s)
{
if( current_level > log_level )
return *this; return *this;
buffer << s; buffer << s;
return *this;
}
Log & Log::operator<<(const char * s)
{
if( current_level > log_level )
return *this;
if( !s )
return *this;
buffer << s;
return *this; return *this;
} }
Log & Log::operator<<(const std::string & s) Log & Log::operator<<(const std::string & s)
{ {
buffer << s; if( current_level > log_level )
return *this;
return *this; buffer << s;
return *this;
} }
Log & Log::operator<<(const std::string * s)
{
if( current_level > log_level )
return *this;
buffer << *s;
return *this;
}
Log & Log::operator<<(const wchar_t * s)
{
if( current_level <= log_level )
{
if( s )
buffer << s;
}
return *this;
}
Log & Log::operator<<(const std::wstring & s)
{
if( current_level <= log_level )
{
buffer << s;
}
return *this;
}
Log & Log::operator<<(const std::wstring * s)
{
if( current_level <= log_level )
{
buffer << *s;
}
return *this;
}
Log & Log::operator<<(int s) Log & Log::operator<<(int s)
{ {
buffer << s; if( current_level <= log_level )
{
buffer << s;
}
return *this; return *this;
} }
Log & Log::operator<<(long s) Log & Log::operator<<(long s)
{ {
buffer << s; if( current_level <= log_level )
{
buffer << s;
}
return *this; return *this;
} }
@@ -68,27 +242,96 @@ Log & Log::operator<<(long s)
Log & Log::operator<<(char s) Log & Log::operator<<(char s)
{ {
buffer << s; if( current_level <= log_level )
{
buffer << s;
}
return *this; return *this;
}
Log & Log::operator<<(wchar_t s)
{
if( current_level <= log_level )
{
buffer << s;
}
return *this;
} }
Log & Log::operator<<(size_t s) Log & Log::operator<<(size_t s)
{ {
buffer << s; if( current_level <= log_level )
{
buffer << s;
}
return *this; return *this;
} }
Log & Log::operator<<(Manipulators m)
Log & Log::operator<<(double s)
{
if( current_level <= log_level )
{
buffer << s;
}
return *this;
}
Log & Log::operator<<(const PT::Space & s)
{
if( current_level <= log_level )
{
buffer << s;
}
return *this;
}
Log & Log::operator<<(const PT::Date & date)
{
if( current_level <= log_level )
{
buffer << date;
}
return *this;
}
Log & Log::operator<<(LogManipulators m)
{ {
switch(m) switch(m)
{ {
case logend: case logend:
SaveLog(); if( current_level <= log_level )
buffer.str( "" ); {
buffer << '\n';
lines += 1;
if( save_each_line )
SaveLogAndClear();
}
break;
case logsave:
SaveLogAndClear();
break;
case logendrequest:
if( ++request >= max_requests || lines > max_lines )
SaveLogAndClear();
break; break;
case log1: case log1:
@@ -102,6 +345,13 @@ Log & Log::operator<<(Manipulators m)
case log3: case log3:
current_level = 3; current_level = 3;
break; break;
case log4:
current_level = 4;
break;
default:
break;
} }
return *this; return *this;
@@ -109,63 +359,129 @@ return *this;
char Log::GetHEXdigit(unsigned char c)
{
if( c < 10 )
return c + '0';
return c - 10 + 'A';
}
void Log::ToHEX(char * buf, unsigned char c)
{
buf[0] = GetHEXdigit(c >> 4);
buf[1] = GetHEXdigit(c & 0xf);
buf[2] = 0;
}
void Log::LogBinary(const char * blob, size_t blob_len)
{
size_t i=0;
char buf[3];
while( i < blob_len )
{
size_t oldi = i;
for(size_t a=0 ; a<16 ; ++a)
{
if( i < blob_len )
{
ToHEX(buf, blob[i]);
buffer << buf << ' ';
++i;
}
else
{
buffer << " ";
}
if( a == 7 )
{
if( i < blob_len )
buffer << "- ";
else
buffer << " ";
}
}
i = oldi;
buffer << ' ';
for(size_t a=0 ; a<16 && i<blob_len ; ++a, ++i)
{
if( blob[i] > 31 && blob[i] < 127 )
buffer << blob[i];
else
buffer << '.';
}
(*this) << logend;
}
}
void Log::LogBinary(const std::string & blob)
{
LogBinary(blob.c_str(), blob.size());
}
void Log::SystemErr(int err)
{
(*this) << "errno: " << err;
const char * err_msg = strerror(err);
if( err_msg )
(*this) << " (" << err_msg << ")";
}
void Log::SaveLogAndClear()
{
SaveLog();
buffer.Clear();
request = 0;
lines = 0;
}
void Log::SaveLog() void Log::SaveLog()
{ {
int attempt = 2; if( buffer.Str().empty() )
return;
if( current_level > log_level ) if( log_stdout )
return; PT::WideToUTF8(buffer.Str(), std::cout);
if( log_stdout ) if( log_file.empty() )
std::cout << buffer.str() << std::endl; return;
if( !log_file_open || !file )
{
file.close();
file.clear();
if( log_file.empty() ) OpenFile();
if( !file )
return; return;
}
std::ofstream file; PT::WideToUTF8(buffer.Str(), file);
file.flush();
do
{
file.open( log_file.c_str(), std::ios_base::out | std::ios_base::app );
// if( !file )
// sleep(1);
}
while( --attempt > 0 && !file );
if( !file )
return;
file << buffer.str() << std::endl;
} }
} // namespace Winix

View File

@@ -1,57 +1,199 @@
/* /*
* This file is a part of CMSLU -- Content Management System like Unix * This file is a part of Winix
* and is not publicly distributed * and is distributed under the 2-Clause BSD licence.
* * Author: Tomasz Sowa <t.sowa@ttmath.org>
* Copyright (c) 2008, Tomasz Sowa */
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/ */
#ifndef headerfilelog #ifndef headerfile_winix_core_log
#define headerfilelog #define headerfile_winix_core_log
#include <sstream> #include <sstream>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <string> #include <string>
#include "textstream.h"
#include "logmanipulators.h"
#include "textstream/textstream.h"
// !! dodac manipulator logsave, logi zostana zapisane pod koniec wykonywania jednego requesta (albo po kilku w zaleznosci od jakiejs opcji w konfigu) namespace Winix
// logsave zostanie wywolane w requestcontroller.cpp przy konczeniu wykonywania requesta {
enum Manipulators { logend, log1, log2, log3 };
class TimeZones;
class Log class Log
{ {
std::ostringstream buffer;
int log_level, current_level;
std::string log_file;
bool log_stdout;
public: public:
Log();
void Init(int log_l, const std::string & log_f, bool log_std);
Log();
~Log();
void SetTimeZones(TimeZones * ptime_zones);
void Init(int log_level_, bool save_each_line_, const std::string & log_file_, bool log_std, int log_max_requests);
Log & operator<<(const void * s);
Log & operator<<(const char * s); Log & operator<<(const char * s);
Log & operator<<(const std::string * s);
Log & operator<<(const std::string & s); Log & operator<<(const std::string & s);
Log & operator<<(const wchar_t * s);
Log & operator<<(const std::wstring * s);
Log & operator<<(const std::wstring & s);
Log & operator<<(int s); Log & operator<<(int s);
Log & operator<<(long s); Log & operator<<(long s);
Log & operator<<(char s); Log & operator<<(char s);
Log & operator<<(wchar_t s);
Log & operator<<(size_t s); Log & operator<<(size_t s);
Log & operator<<(Manipulators m); Log & operator<<(double s);
Log & operator<<(const PT::Space & space);
Log & operator<<(LogManipulators m);
Log & operator<<(const PT::Date & date);
void PrintDate(const PT::Date & date, size_t time_zone_id);
template<typename char_type, size_t stack_size, size_t heap_block_size>
Log & operator<<(const PT::TextStreamBase<char_type, stack_size, heap_block_size> & buf);
template<class StringType>
void LogString(const StringType & value, size_t max_size);
void LogBinary(const char * blob, size_t blob_len);
void LogBinary(const std::string & blob);
void SystemErr(int err);
void SaveLog(); void SaveLog();
void SaveLogAndClear();
int LogLevel();
private:
// time zones for printing the time in the log file
TimeZones * time_zones;
// buffer for the log
TextStream<std::wstring> buffer;
// log lovel from the config file
int log_level;
// current level set by a modifier (e.g. log << log3)
int current_level;
// current request for logging
// starts from zero and incremented after logendrequest modifier
int request;
// how many request to save at once
int max_requests;
// file log
std::string log_file;
std::ofstream file;
// logging to stdout
bool log_stdout;
// how many lines there are in the buffer
int lines;
// is the config file already open
bool log_file_open;
// how many lines can be in the config buffer
// default: 5000
int max_lines;
// whether to save each line (for debug)
bool save_each_line;
void OpenFile();
char GetHEXdigit(unsigned char c);
void ToHEX(char * buf, unsigned char c);
}; };
extern Log log; template<class StringType>
void Log::LogString(const StringType & value, size_t max_size)
{
size_t min_size = value.size() < max_size ? value.size() : max_size;
if( current_level <= log_level )
{
for(size_t i=0 ; i<min_size ; ++i)
{
if( value[i] < 32 )
buffer << '.';
else
buffer << value[i];
}
}
}
template<typename char_type, size_t stack_size, size_t heap_block_size>
Log & Log::operator<<(const PT::TextStreamBase<char_type, stack_size, heap_block_size> & buf)
{
if( current_level <= log_level )
buffer << buf;
return *this;
}
extern Log log;
extern Log nlog;
} // namespace Winix
// for convenience, we have to use only #include "log.h" in the winix
#include "slog.h"
#endif #endif

83
core/logmanipulators.h Executable file
View File

@@ -0,0 +1,83 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2011-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_logmanipulators
#define headerfile_winix_core_logmanipulators
namespace Winix
{
/*
log1 - the first level
log2
log3
log4 - the last level (debug level)
logend - the end of a line
logendrequest - end of a current request
logsave - current log buffer is saved and cleared
manipulators used by the session logger (SLog)
loginfo - normal info to a user
logerror - we are reporting an error
logwarning - we are reporting a warning
make sure that loginfo, logerror and logwarning have values less than 32 (space)
their are used as control codes in a string
*/
enum LogManipulators
{
log1,
log2,
log3,
log4,
logend,
logendrequest,
logsave,
loginfo,
logerror,
logwarning
};
} // namespace Winix
#endif

View File

@@ -1,118 +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 <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"
// singletons
// first 'data' then 'log' then 'request'
Data data;
Log log;
Request request;
Db db;
Config config;
void signal_term(int)
{
log << log1 << "cmslu stopped" << logend;
exit(0);
}
void signal_hup(int)
{
log << log3 << "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)
{
RequestController req_controller;
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
close(2);
if( !data.log_stdout )
{
close(1);
data.stdout_is_closed = true;
}
signal(SIGTERM, signal_term);
signal(SIGINT, signal_term);
signal(SIGHUP, signal_hup);
while( true )
{
log.Init(data.log_level, data.log_file, data.log_stdout);
db.Init(data.db_database, data.db_user, data.db_pass);
if( !req_controller.Init() )
return 1;
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;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

145
core/mount.cpp Executable file
View File

@@ -0,0 +1,145 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2009-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "mount.h"
#include "misc.h"
namespace Winix
{
Mount::Mount()
{
dir_id = -1;
type = -1;
fs = -1;
}
void Mount::ClearParams()
{
size_t i;
for(i=0 ; i<param.size() ; ++i)
param[i].Clear();
}
bool Mount::IsPar(int code)
{
if( code < 0 || code >= (int)param.size() )
return false;
if( !param[code].defined )
return false;
return true;
}
bool Mount::IsArg(int code, const wchar_t * arg)
{
ParamRow::ParamArg::iterator i;
if( code < 0 || code >= (int)param.size() )
return false;
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(int code, const std::wstring & arg)
{
return IsArg(code, arg.c_str());
}
bool Mount::IsArg(int code, int arg)
{
ParamRow::ParamArg::iterator i;
if( code < 0 || code >= (int)param.size() )
return false;
if( !param[code].defined )
return false;
for(i=param[code].arg.begin() ; i!=param[code].arg.end() ; ++i)
{
if( Toi(*i) == arg )
return true;
}
return false;
}
const std::wstring & Mount::Arg(int code, int arg) const
{
if( code < 0 || code >= (int)param.size() )
return empty_str;
if( !param[code].defined )
return empty_str;
if( arg >= (int)param[code].arg.size() )
return empty_str;
return param[code].arg[arg];
}
const std::wstring & Mount::FirstArg(int code) const
{
return Arg(code, 0);
}
} // namespace Winix

103
core/mount.h Executable file
View File

@@ -0,0 +1,103 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2009-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_mount
#define headerfile_winix_core_mount
#include <map>
#include <string>
#include <vector>
namespace Winix
{
class Mount
{
public:
struct ParamRow
{
typedef std::vector<std::wstring> ParamArg;
bool defined;
ParamArg arg;
ParamRow() { defined = false; }
void Clear() { defined = false; arg.clear(); }
};
typedef std::vector<ParamRow> Param;
long dir_id;
int type;
int fs;
Param param;
Mount();
void ClearParams();
bool IsPar(int code);
bool IsArg(int code, const wchar_t * arg);
bool IsArg(int code, const std::wstring & arg);
bool IsArg(int code, int arg);
// returning the arg argument if defined (or an empty string)
const std::wstring & Arg(int code, int arg) const;
// returning the first argument (arg=0) if defined (or an empty string)
const std::wstring & FirstArg(int code) const;
private:
// for Arg() methods when the argument is not defined
const std::wstring empty_str;
};
} // namespace Winix
#endif

528
core/mountparser.cpp Executable file
View File

@@ -0,0 +1,528 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2010-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "mountparser.h"
#include "log.h"
#include "misc.h"
namespace Winix
{
MountParser::MountParser()
{
dirs = 0;
skip_static = false;
mount_type_tab = 0;
mount_fs_tab = 0;
mount_par_tab = 0;
static_mount_id = -1;
}
void MountParser::SkipStaticDirs(bool skip)
{
skip_static = skip;
}
void MountParser::SetStaticMountId(int id)
{
static_mount_id = id;
}
void MountParser::SetDirs(Dirs * pdirs)
{
dirs = pdirs;
}
void MountParser::SetMountTypeTab(const std::vector<std::wstring> & tab)
{
mount_type_tab = &tab;
}
void MountParser::SetMountFsTab(const std::vector<std::wstring> & tab)
{
mount_fs_tab = &tab;
}
void MountParser::SetMountParTab(const std::vector<std::wstring> & tab)
{
mount_par_tab = &tab;
}
bool MountParser::IsWhite(int c)
{
if( c==' ' || c=='\t' || c==13 || c==160 )
return true;
return false;
}
void MountParser::SkipWhite()
{
while( IsWhite(*pinput) )
++pinput;
}
void MountParser::SkipLine()
{
while( *pinput && *pinput != 10 )
++pinput;
if( *pinput == 10 )
++pinput;
}
void MountParser::ReadWordQuote(std::wstring & res)
{
++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::wstring & res)
{
while( *pinput && *pinput!=10 && !IsWhite(*pinput) )
{
res += *pinput;
++pinput;
}
}
// the comma or the second bracket ')' are the separators
void MountParser::ReadWordComma(std::wstring & res)
{
while( *pinput && *pinput!=10 && *pinput!=',' && *pinput!=')' )
{
res += *pinput;
++pinput;
}
// trimming last white characters
// (white characters can be in the middle of the string)
TrimWhite(res);
}
void MountParser::ReadWord(std::wstring & res, bool comma_bracket_separator)
{
res.clear();
SkipWhite();
if( *pinput == '"' )
{
ReadWordQuote(res);
}
else
if( comma_bracket_separator )
{
ReadWordComma(res);
}
else
{
ReadWordWhite(res);
}
}
void MountParser::ReadParamArgsLoop(Mount::ParamRow::ParamArg & args)
{
SkipWhite();
while( *pinput && *pinput!=10 && *pinput!=')' )
{
ReadWord(temp_arg, true);
if( !temp_arg.empty() )
args.push_back(temp_arg);
if( *pinput == ',' )
++pinput;
}
}
void MountParser::ReadParamArgs(Mount::ParamRow::ParamArg & args)
{
SkipWhite();
args.clear();
if( *pinput == '(' )
{
++pinput;
ReadParamArgsLoop(args);
if( *pinput != ')' )
{
// there should be ')' at the end
// temporarily we do nothing
}
else
{
++pinput;
}
}
}
void MountParser::ReadParamName(std::wstring & res)
{
SkipWhite();
res.clear();
while( *pinput && *pinput!=10 && *pinput!=',' && *pinput!='(' && !IsWhite(*pinput) )
{
res += *pinput;
++pinput;
}
}
void MountParser::ReadParam(std::wstring & res, Mount::ParamRow::ParamArg & args)
{
ReadParamName(res);
if( res.empty() )
return;
ReadParamArgs(args);
SkipWhite();
if( *pinput == ',' )
++pinput;
}
int MountParser::FindIndex(const std::vector<std::wstring> * tab, const std::wstring & value)
{
for(size_t i=0 ; i < tab->size() ; ++i)
{
if( (*tab)[i] == value )
return static_cast<int>(i);
}
return -1;
}
bool MountParser::ReadMountType()
{
ReadWord(temp);
if( temp.empty() )
{
// an empty line (some white characters only)
return false;
}
mount.type = FindIndex(mount_type_tab, temp);
if( mount.type != -1 )
{
log << log3 << "MP: mount type: " << (*mount_type_tab)[mount.type] << logend;
}
else
{
log << log1 << "MP: unknown mount type: " << temp << logend;
slog << logerror << T("unknown_mount_type") << ": " << temp << logend;
}
return mount.type != -1;
}
bool MountParser::ReadMountPoint()
{
ReadWord(last_dir);
pdir = dirs->GetDir(last_dir);
if( pdir )
{
mount.dir_id = pdir->id;
log << log3 << "MP: mount point (directory): " << last_dir << logend;
}
else
{
log << log1 << "MP: there is no such a mount point (directory): " << last_dir << logend;
slog << logerror << T("no_such_dir") << ": " << last_dir << logend;
}
return pdir != 0;
}
bool MountParser::ReadFs()
{
ReadWord(temp);
mount.fs = FindIndex(mount_fs_tab, temp);
if( mount.fs != -1 )
{
log << log2 << "MP: file system: " << (*mount_fs_tab)[mount.fs] << logend;
}
else
{
log << log1 << "MP: unknown filesystem: " << temp << logend;
slog << logerror << T("unknown_filesystem") << ": " << temp << " (" << last_dir << ")" << logend;
}
return mount.fs != -1;
}
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) )
{
int code = FindIndex(mount_par_tab, temp);
if( code != -1 )
{
mount.param[code].defined = true;
mount.param[code].arg = param_args;
LogMountParams();
}
else
{
log << log1 << "MP: unknown mount param: " << temp << logend;
slog << logwarning << T("unknown_mount_param") << ": " << temp << " (" << T("skipped") << ")" << logend;
}
}
}
void MountParser::AddParams(Mount::Param & src, Mount::Param & dst)
{
if( src.size() != dst.size() )
{
log << log1 << "MP: addparams: incorrect sizes" << logend;
return;
}
for(size_t p=0 ; p < src.size() ; ++p)
{
if( src[p].defined && !dst[p].defined )
dst[p] = src[p];
}
}
bool MountParser::AddParamsBefore(long dir_id)
{
std::map<long, Mount>::iterator i = poutput->find(dir_id);
if( i == poutput->end() )
return false;
AddParams(i->second.param, mount_inserted.first->second.param);
return true;
}
/*
adding all non-existing parameters to this mount point from parents
*/
void MountParser::AddParamsBefore()
{
if( !pdir )
return;
Item * dir;
long dir_id = pdir->parent_id;
while( dir_id != -1 )
{
if( AddParamsBefore(dir_id) )
{
// we don't have to check others parents
// the parameters are already copied
break;
}
dir = dirs->GetDir(dir_id);
if( !dir )
break;
dir_id = dir->parent_id;
}
}
/*
adding all non-existing parameters to childs (childs to this mount point)
*/
void MountParser::AddParamsAfter()
{
std::map<long, Mount>::iterator i = poutput->begin();
for( ; i != poutput->end() ; ++i)
{
if( dirs->IsChild(mount_inserted.first->second.dir_id, i->first) )
AddParams(mount_inserted.first->second.param, i->second.param);
}
}
void MountParser::ReadRow()
{
if( ReadMountType() && ReadMountPoint() && ReadFs() )
{
ReadMountParams();
if( skip_static && mount.type==static_mount_id )
{
log << log1 << "MP: static mount points are skipped (dont_use_static_dirs in config is true)" << logend;
slog << logwarning << T("skipped_static_mount") << ": " << last_dir << logend;
}
else
{
mount_inserted = poutput->insert( std::make_pair(mount.dir_id, mount) );
if( mount_inserted.second )
{
AddParamsBefore();
AddParamsAfter();
}
else
{
log << log1 << "MP: this mount point exists (skipped)" << logend;
slog << logwarning << T("mount_exists") << ": " << last_dir << " (" << T("skipped") << ")" << logend;
}
}
}
SkipLine();
}
void MountParser::Parse(const std::wstring & input, std::map<long, Mount> & output)
{
if( !dirs || !mount_type_tab || !mount_fs_tab || !mount_par_tab )
{
log << log1 << "MP: input tables not set" << logend;
return;
}
pinput = input.c_str();
poutput = &output;
mount.param.resize(mount_par_tab->size());
mount.ClearParams();
poutput->clear();
while( *pinput )
ReadRow();
}
} // namespace Winix

119
core/mountparser.h Executable file
View File

@@ -0,0 +1,119 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2010-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_mountparser
#define headerfile_winix_core_mountparser
#include <map>
#include <string>
#include <vector>
#include <stdlib.h>
#include <limits.h>
#include "mount.h"
#include "item.h"
#include "dirs.h"
namespace Winix
{
class MountParser
{
public:
MountParser();
void SkipStaticDirs(bool skip);
void SetStaticMountId(int id);
void Parse(const std::wstring & input, std::map<long, Mount> & output);
void SetDirs(Dirs * pdirs);
void SetMountTypeTab(const std::vector<std::wstring> & tab);
void SetMountFsTab(const std::vector<std::wstring> & tab);
void SetMountParTab(const std::vector<std::wstring> & tab);
private:
Dirs * dirs;
bool skip_static;
int static_mount_id;
const std::vector<std::wstring> * mount_type_tab;
const std::vector<std::wstring> * mount_fs_tab;
const std::vector<std::wstring> * mount_par_tab;
bool IsWhite(int c);
void SkipWhite();
void SkipLine();
void ReadWordQuote(std::wstring & res);
void ReadWordWhite(std::wstring & res);
void ReadWordComma(std::wstring & res);
void ReadWord(std::wstring & res, bool comma_bracket_separator = false);
void ReadParamArgsLoop(Mount::ParamRow::ParamArg & args);
void ReadParamArgs(Mount::ParamRow::ParamArg & args);
void ReadParamName(std::wstring & res);
void ReadParam(std::wstring & res, Mount::ParamRow::ParamArg & args);
int FindIndex(const std::vector<std::wstring> * tab, const std::wstring & value);
bool ReadMountType();
bool ReadMountPoint();
bool ReadFs();
void LogMountParams();
void ReadMountParams();
void ReadRow();
void AddParams(Mount::Param & src, Mount::Param & dst);
bool AddParamsBefore(long dir_id);
void AddParamsBefore();
void AddParamsAfter();
const wchar_t * pinput;
std::wstring temp;
std::wstring last_dir;
std::wstring temp_arg;
Mount::ParamRow::ParamArg param_args;
Mount mount;
Item * pdir;
std::map<long, Mount> * poutput;
std::pair<std::map<long, Mount>::iterator, bool> mount_inserted;
};
} // namespace Winix
#endif

357
core/mounts.cpp Executable file
View File

@@ -0,0 +1,357 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2009-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "mounts.h"
#include "request.h"
#include "log.h"
#include "db/db.h"
#include "plugin.h"
namespace Winix
{
Mounts::Mounts()
{
pmount = &empty_mount;
skip_static = false;
}
void Mounts::SkipStaticDirs(bool skip)
{
skip_static = skip;
}
void Mounts::CreateMountType()
{
mount_type_cms = AddMountType(L"cms");
mount_type_static = AddMountType(L"static");
}
void Mounts::CreateMountFs()
{
mount_fs_simplefs = AddMountFs(L"simplefs");
mount_fs_hashfs = AddMountFs(L"hashfs");
}
void Mounts::CreateMountPar()
{
mount_par_page = AddMountPar(L"page");
mount_par_thumb_size = AddMountPar(L"thumb_size");
mount_par_thumb_mode = AddMountPar(L"thumb_mode");
mount_par_thumb_quality = AddMountPar(L"thumb_quality");
mount_par_image_size = AddMountPar(L"image_size");
mount_par_image_mode = AddMountPar(L"image_mode");
mount_par_image_quality = AddMountPar(L"image_quality");
mount_par_emacs_on = AddMountPar(L"emacs_on");
mount_par_mkdir_on = AddMountPar(L"mkdir_on");
mount_par_app = AddMountPar(L"app");
mount_par_html_template = AddMountPar(L"html_template");
mount_par_change_template = AddMountPar(L"change_template");
mount_par_static = AddMountPar(L"static");
mount_par_css = AddMountPar(L"css");
mount_par_lang = AddMountPar(L"lang");
}
void Mounts::CreateMounts()
{
CreateMountType();
CreateMountFs();
CreateMountPar();
plugin.Call((Session*)0, WINIX_ADD_MOUNTS);
empty_mount.param.resize(mount_par_tab.size());
empty_mount.ClearParams();
}
void Mounts::SetDirs(Dirs * pdirs)
{
dirs = pdirs;
}
void Mounts::SetDb(Db * pdb)
{
db = pdb;
}
void Mounts::SetCur(Cur * pcur)
{
cur = pcur;
}
int Mounts::AddMountType(const wchar_t * type)
{
mount_type_tab.push_back(type);
return static_cast<int>(mount_type_tab.size()) - 1;
}
int Mounts::AddMountType(const std::wstring & type)
{
return AddMountType(type.c_str());
}
int Mounts::AddMountFs(const wchar_t * fs)
{
mount_fs_tab.push_back(fs);
return static_cast<int>(mount_fs_tab.size()) - 1;
}
const std::wstring & Mounts::GetMountType(int id)
{
if( id < 0 || id >= (int)mount_type_tab.size() )
return empty_str;
return mount_type_tab[id];
}
int Mounts::FindMountType(const std::wstring & type)
{
for(size_t i=0 ; i<mount_type_tab.size() ; ++i)
if( mount_type_tab[i] == type )
return (int)i;
return -1;
}
int Mounts::AddMountFs(const std::wstring & fs)
{
return AddMountFs(fs.c_str());
}
const std::wstring & Mounts::GetMountFs(int id)
{
if( id < 0 || id >= (int)mount_fs_tab.size() )
return empty_str;
return mount_fs_tab[id];
}
int Mounts::AddMountPar(const wchar_t * par)
{
mount_par_tab.push_back(par);
return static_cast<int>(mount_par_tab.size()) - 1;
}
int Mounts::AddMountPar(const std::wstring & par)
{
return AddMountPar(par.c_str());
}
const std::wstring & Mounts::GetMountPar(int id)
{
if( id < 0 || id >= (int)mount_par_tab.size() )
return empty_str;
return mount_par_tab[id];
}
// reading from 'mounts'
void Mounts::ReadMounts(const std::wstring & mounts)
{
mount_parser.SkipStaticDirs(skip_static);
mount_parser.SetStaticMountId(mount_type_static);
mount_parser.SetDirs(dirs);
mount_parser.SetMountTypeTab(mount_type_tab);
mount_parser.SetMountFsTab(mount_fs_tab);
mount_parser.SetMountParTab(mount_par_tab);
mount_parser.Parse(mounts, mount_tab);
CalcCurMount();
plugin.Call((Session*)0, WINIX_FSTAB_CHANGED);
}
// reading from /etc/fstab
Error Mounts::ReadMounts()
{
static std::wstring file = L"fstab";
Item * etc = dirs->GetEtcDir();
if( !etc )
{
log << log1 << "M: there is no /etc directory" << logend;
return WINIX_ERR_NO_ITEM;
}
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;
}
ReadMounts(fstab.content);
return WINIX_ERR_OK;
}
void Mounts::MountCmsForRoot()
{
Mount mount;
mount.type = MountTypeCms();
mount.fs = MountFsSimplefs();
Item * proot = dirs->GetRootDir();
if( proot )
mount.dir_id = proot->id;
else
{
mount.dir_id = -1;
log << log1 << "M: there is no a root dir" << logend;
}
mount.param.resize(mount_par_tab.size());
mount.ClearParams();
std::pair<MountTab::iterator, bool> res = mount_tab.insert( std::make_pair(mount.dir_id, mount) );
pmount = &(res.first->second);
}
Mount * Mounts::CalcCurMount()
{
std::vector<Item*>::reverse_iterator i;
pmount = &empty_mount;
// when the program starts (when the dir_tab is empty()
// we don't want to call MountCmsForRoot()
if( cur->request->dir_tab.empty() )
return pmount;
for(i = cur->request->dir_tab.rbegin() ; i!=cur->request->dir_tab.rend() ; ++i)
{
std::map<long, Mount>::iterator m = mount_tab.find( (*i)->id );
if( m != mount_tab.end() )
{
pmount = &(m->second);
log << log2 << "M: current mount point is: " << GetMountType(pmount->type)
<< ", fs: " << GetMountFs(pmount->fs) << logend;
return pmount;
}
}
// if nothing was found
// we assume that 'cms' mount point is used
MountCmsForRoot();
log << log2 << "M: current mount point is: " << GetMountType(pmount->type) << " (default)"
<< ", fs: " << GetMountFs(pmount->fs) << logend;
return pmount;
}
// 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;
}
Mount * Mounts::GetEmptyMount()
{
return &empty_mount;
}
} // namespace Winix

202
core/mounts.h Executable file
View File

@@ -0,0 +1,202 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2009-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_mounts
#define headerfile_winix_core_mounts
#include <map>
#include <string>
#include <vector>
#include "mount.h"
#include "error.h"
#include "dirs.h"
#include "db/db.h"
#include "request.h"
#include "mountparser.h"
namespace Winix
{
class Mounts
{
public:
void SkipStaticDirs(bool skip);
/*
mount point's types
*/
int AddMountType(const wchar_t * type);
int AddMountType(const std::wstring & type);
const std::wstring & GetMountType(int id);
// id of a specific mount type (the id is always valid)
int MountTypeCms() { return mount_type_cms; }
int MountTypeStatic() { return mount_type_static; }
// return -1 if there is no such a mount type
// or index otherwhise
int FindMountType(const std::wstring & type);
/*
file systems
*/
int AddMountFs(const wchar_t * fs);
int AddMountFs(const std::wstring & fs);
const std::wstring & GetMountFs(int id);
// id of a specific file system (the id is always valid)
int MountFsSimplefs() { return mount_fs_simplefs; }
int MountFsHashfs() { return mount_fs_hashfs; }
/*
mount point's parameters
*/
int AddMountPar(const wchar_t * par);
int AddMountPar(const std::wstring & par);
const std::wstring & GetMountPar(int id);
int MountParPage() { return mount_par_page; }
int MountParThumbSize() { return mount_par_thumb_size; }
int MountParThumbMode() { return mount_par_thumb_mode; }
int MountParThumbQuality() { return mount_par_thumb_quality; }
int MountParImageSize() { return mount_par_image_size; }
int MountParImageMode() { return mount_par_image_mode; }
int MountParImageQuality() { return mount_par_image_quality; }
int MountParEmacsOn() { return mount_par_emacs_on; }
int MountParMkdirOn() { return mount_par_mkdir_on; }
int MountParApp() { return mount_par_app; }
int MountParHtmlTemplate() { return mount_par_html_template; }
int MountParChangeTemplate() { return mount_par_change_template; }
int MountParStatic() { return mount_par_static; }
int MountParCss() { return mount_par_css; }
int MountParLang() { return mount_par_lang; }
void SetDirs(Dirs * pdirs);
void SetDb(Db * pdb);
void SetCur(Cur * pcur);
// dir_id, mount_point
typedef std::map<long, Mount> MountTab;
Mounts();
void CreateMounts();
void ReadMounts(const std::wstring & mounts);
Error ReadMounts();
Mount * CalcCurMount();
Mount * CalcMount(long dir_id);
// current mount point
// will not be null after calling CalcCurMount() or ReadMounts([...])
// !! nie korzystac obecnie z niego
// korzystac z cur->mount
// a tez zostanie wycofany
Mount * pmount;
const MountTab * GetMountTab();
// at the beginning used to initialize cur->mount
Mount * GetEmptyMount();
private:
Db * db;
Dirs * dirs;
Cur * cur;
bool skip_static;
Mount empty_mount;
const std::wstring empty_str;
MountParser mount_parser;
std::vector<std::wstring> mount_type_tab;
int mount_type_cms;
int mount_type_static;
// simplefs
// hashfs
std::vector<std::wstring> mount_fs_tab;
int mount_fs_simplefs;
int mount_fs_hashfs;
std::vector<std::wstring> mount_par_tab;
int mount_par_page;
int mount_par_thumb_size;
int mount_par_thumb_mode;
int mount_par_thumb_quality;
int mount_par_image_size;
int mount_par_image_mode;
int mount_par_image_quality;
int mount_par_emacs_on;
int mount_par_mkdir_on;
int mount_par_app;
int mount_par_html_template;
int mount_par_change_template;
int mount_par_static;
int mount_par_css;
int mount_par_lang;
MountTab mount_tab;
void CreateMountType();
void CreateMountFs();
void CreateMountPar();
void MountCmsForRoot();
};
} // namespace Winix
#endif

533
core/plugin.cpp Executable file
View File

@@ -0,0 +1,533 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <dlfcn.h>
#include <string.h>
#include "plugin.h"
#include "pluginmsg.h"
#include "misc.h"
namespace Winix
{
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;
db = 0;
config = 0;
cur = 0;
system = 0;
functions = 0;
templates = 0;
synchro = 0;
session_manager = 0;
}
Plugin::~Plugin()
{
UnloadPlugins();
}
void Plugin::SetDb(Db * pdb)
{
db = pdb;
}
void Plugin::SetConfig(Config * pconfig)
{
config = pconfig;
}
void Plugin::SetCur(Cur * pcur)
{
cur = pcur;
}
void Plugin::SetSystem(System * psystem)
{
system = psystem;
}
void Plugin::SetFunctions(Functions * pfunctions)
{
functions = pfunctions;
}
void Plugin::SetTemplates(Templates * ptemplates)
{
templates = ptemplates;
}
void Plugin::SetSynchro(Synchro * psynchro)
{
synchro = psynchro;
}
void Plugin::SetSessionManager(SessionManager * psession_manager)
{
session_manager = psession_manager;
}
void Plugin::Lock()
{
if( synchro )
synchro->Lock();
}
void Plugin::Unlock()
{
if( synchro )
synchro->Unlock();
}
bool Plugin::SetPointers(PluginInfo & info)
{
// for safety we call a plugin function only when all our pointers are not null
bool res = (db && config && cur && system && functions && templates && synchro && session_manager);
if( !res )
{
Lock();
log << log1 << "Plugin: cannot call a function - some of the winix pointers are null" << logend;
Unlock();
}
info.db = db;
info.config = config;
info.cur = cur;
info.system = system;
info.functions = functions;
info.templates = templates;
info.synchro = synchro;
info.session_manager = session_manager;
return res;
}
void Plugin::LoadPlugins(const std::wstring & plugins_dir, const std::vector<std::wstring> & plugins)
{
for(size_t i=0 ; i<plugins.size() ; ++i)
{
if( !plugins[i].empty() && plugins[i][0] == '/' )
{
LoadPlugin(plugins[i]);
}
else
{
temp_path = plugins_dir;
temp_path += '/';
temp_path += plugins[i];
LoadPlugin(temp_path);
}
}
}
void Plugin::LoadPlugin(const std::string & filename)
{
LoadPlugin(filename.c_str());
}
// we don't have to use Lock() here because plusings are read
// before threads are started
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)dlsym(p, "Init");
if( !fun_init )
{
log << log1 << "Plugin: cannot load a plugin: " << filename
<< " (there is no Init() function)" << logend;
dlclose(p);
return 0;
}
log << log2 << "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;
PluginInfo info;
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 wchar_t *>(info.p1);
plugins.push_back(item);
current_plugin = old_current_plugin;
}
void Plugin::LoadPlugin(const wchar_t * filename)
{
AssignString(filename, afilename);
LoadPlugin(afilename.c_str());
}
void Plugin::LoadPlugin(const std::wstring & filename)
{
LoadPlugin(filename.c_str());
}
bool Plugin::HasPlugin(const wchar_t * name)
{
if( *name == 0 )
return false;
for(size_t i=0 ; i<plugins.size() ; ++i)
{
if( plugins[i].plugin_name && Equal(plugins[i].plugin_name, name) )
return true;
}
return false;
}
bool Plugin::HasPlugin(const std::wstring & name)
{
return HasPlugin(name.c_str());
}
bool Plugin::HasMessage(int message)
{
return (slots.find(message) != slots.end());
}
void Plugin::Call(Session * ses, int message, Slots::iterator & slot, PluginInfo & info)
{
if( !SetPointers(info) )
return;
current_plugin = slot->second.index;
info.plugin_id = current_plugin;
info.session = ses;
if( current_plugin != -1 && ses )
info.plugin_data_base = ses->plugin_data.Get(current_plugin);
else
info.plugin_data_base = 0;
if( !slot->second.is_running )
{
if( config->log_plugin_call )
{
Lock();
log << log1 << "Plugin: calling plugin id: " << slot->second.index << ", message: " << message << logend;
Unlock();
}
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;
if( config->log_plugin_call )
{
Lock();
log << log1 << "Plugin: returning from plugin id: " << slot->second.index << ", message: " << message
<< ", result: " << (info.res? "true" : "false") << logend;
Unlock();
}
}
else
{
Lock();
log << log1 << "Plugin: id: " << slot->second.index
<< ", message: " << message
<< ", recurrences are not allowed" << logend;
Unlock();
}
}
PluginRes Plugin::Call(Session * ses, int message, void * p1_, void * p2_, long l1_, long l2_)
{
PluginRes res;
int old_current_plugin = current_plugin;
PluginInfo info;
Slots::iterator i = slots.lower_bound(message);
for( ; i!=slots.end() && i->first==message ; ++i )
{
info.Clear();
info.p1 = p1_;
info.p2 = p2_;
info.l1 = l1_;
info.l2 = l2_;
Call(ses, message, i, info);
if( info.res )
++res.res_true;
else
++res.res_false;
}
current_plugin = old_current_plugin;
return res;
}
PluginRes Plugin::Call(int message)
{
return Call(cur->session, message, 0, 0, 0, 0);
}
PluginRes Plugin::Call(int message, void * p1_)
{
return Call(cur->session, message, p1_, 0, 0, 0);
}
PluginRes Plugin::Call(int message, void * p1_, void * p2_)
{
return Call(cur->session, message, p1_, p2_, 0, 0);
}
PluginRes Plugin::Call(int message, long l1_)
{
return Call(cur->session, message, 0, 0, l1_, 0);
}
PluginRes Plugin::Call(int message, long l1_, long l2_)
{
return Call(cur->session, message, 0, 0, l1_, l2_);
}
PluginRes Plugin::Call(int message, void * p1_, long l1_)
{
return Call(cur->session, message, p1_, 0, l1_, 0);
}
PluginRes Plugin::Call(int message, void * p1_, long l1_, long l2_)
{
return Call(cur->session, message, p1_, 0, l1_, l2_);
}
PluginRes Plugin::Call(int message, void * p1_, void * p2_, long l1_)
{
return Call(cur->session, message, p1_, p2_, l1_, 0);
}
PluginRes Plugin::Call(Session * ses, int message)
{
return Call(ses, message, 0, 0, 0, 0);
}
PluginRes Plugin::Call(Session * ses, int message, void * p1_)
{
return Call(ses, message, p1_, 0, 0, 0);
}
PluginRes Plugin::Call(Session * ses, int message, void * p1_, void * p2_)
{
return Call(ses, message, p1_, p2_, 0, 0);
}
PluginRes Plugin::Call(Session * ses, int message, long l1_)
{
return Call(ses, message, 0, 0, l1_, 0);
}
PluginRes Plugin::Call(Session * ses, int message, long l1_, long l2_)
{
return Call(ses, message, 0, 0, l1_, l2_);
}
PluginRes Plugin::Call(Session * ses, int message, void * p1_, long l1_)
{
return Call(ses, message, p1_, 0, l1_, 0);
}
PluginRes Plugin::Call(Session * ses, int message, void * p1_, long l1_, long l2_)
{
return Call(ses, message, p1_, 0, l1_, l2_);
}
PluginRes Plugin::Call(Session * ses, int message, void * p1_, void * p2_, long l1_)
{
return Call(ses, message, p1_, p2_, l1_, 0);
}
size_t Plugin::Size()
{
return plugins.size();
}
/*
!! IMPROVE ME
Assign() can work only if other threads are not started
we can add some barrier/flag so when other threads starts
then we cannot use Assign() method
*/
void Plugin::Assign(int message, Fun1 fun1)
{
Slot s;
if( current_plugin == -1 )
return;
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;
if( current_plugin == -1 )
return;
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;
}
const Plugin::Plugins * Plugin::GetPlugins()
{
return &plugins;
}
} // namespace Winix

284
core/plugin.h Executable file
View File

@@ -0,0 +1,284 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_plugin
#define headerfile_winix_core_plugin
#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 "synchro.h"
#include "functions/functions.h"
#include "templates/templates.h"
namespace Winix
{
/*
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;
Cur * cur;
System * system;
Functions * functions;
Templates * templates;
Synchro * synchro;
SessionManager * session_manager;
// a session
// some messages are sent in a session's context e.g. logging a user
// this pointer in not always the same as cur->session, it is preferred
// to use this pointer instead of cur->session
// (cur->session can point at a temporary object)
// this pointer can be null
Session * session;
// pointer to the plugin session (can be null if not set by the plugin or if session is null)
// this is taken from session->plugin_data.Get()
// you should use WINIX_SESSION_CREATED and WINIX_PLUGIN_SESSION_DATA_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 res;
void Clear()
{
// pointers to winix objects are not cleared here
p1 = 0;
p2 = 0;
l1 = 0;
l2 = 0;
plugin_id = -1;
session = 0;
plugin_data_base = 0;
res = false;
}
};
/*
this structure tells how many plugins returned true and false
*/
struct PluginRes
{
int res_false;
int res_true;
PluginRes()
{
res_false = 0;
res_true = 0;
}
};
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;
}
};
struct PluginsItem
{
void * handle;
const wchar_t * plugin_name; // plugin name (can be null if was not set by the plugin)
};
typedef std::vector<PluginsItem> Plugins;
Plugin();
~Plugin();
void SetDb(Db * pdb);
void SetConfig(Config * pconfig);
void SetCur(Cur * pcur);
void SetSystem(System * psystem);
void SetFunctions(Functions * pfunctions);
void SetTemplates(Templates * ptemplates);
void SetSynchro(Synchro * psynchro);
void SetSessionManager(SessionManager * psession_manager);
void LoadPlugin(const char * filename);
void LoadPlugin(const std::string & filename);
void LoadPlugin(const wchar_t * filename);
void LoadPlugin(const std::wstring & filename);
void LoadPlugins(const std::wstring & plugins_dir, const std::vector<std::wstring> & plugins);
void UnloadPlugins();
bool HasPlugin(const wchar_t * name);
bool HasPlugin(const std::wstring & name);
bool HasMessage(int message);
PluginRes Call(int message);
PluginRes Call(int message, void * p1_);
PluginRes Call(int message, void * p1_, void * p2_);
PluginRes Call(int message, long l1_);
PluginRes Call(int message, long l1_, long l2_);
PluginRes Call(int message, void * p1_, long l1_);
PluginRes Call(int message, void * p1_, long l1_, long l2_);
PluginRes Call(int message, void * p1_, void * p2_, long l1_);
PluginRes Call(Session * ses, int message, void * p1_, void * p2_, long l1_, long l2_);
PluginRes Call(Session * ses, int message);
PluginRes Call(Session * ses, int message, void * p1_);
PluginRes Call(Session * ses, int message, void * p1_, void * p2_);
PluginRes Call(Session * ses, int message, long l1_);
PluginRes Call(Session * ses, int message, long l1_, long l2_);
PluginRes Call(Session * ses, int message, void * p1_, long l1_);
PluginRes Call(Session * ses, int message, void * p1_, long l1_, long l2_);
PluginRes Call(Session * ses, int message, void * p1_, void * p2_, long l1_);
// 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);
// return a const pointer to the plugin tab
const Plugins * GetPlugins();
private:
Db * db;
Config * config;
Cur * cur;
System * system;
Functions * functions;
Templates * templates;
Synchro * synchro;
SessionManager * session_manager;
std::wstring temp_path; // used when loading plugins
std::string afilename;
Plugins plugins;
typedef std::multimap<int, Slot> Slots;
Slots slots;
void * LoadInitFun(const char * filename, Fun1 & fun_init);
void Call(Session * ses, int message, Slots::iterator & slot, PluginInfo & info);
bool SetPointers(PluginInfo & info);
void Lock();
void Unlock();
};
extern Plugin plugin;
} // namespace Winix
#endif

189
core/plugindata.cpp Executable file
View File

@@ -0,0 +1,189 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "plugindata.h"
#include "plugin.h"
#include "log.h"
#include "session.h"
namespace Winix
{
PluginData::PluginData()
{
session = 0;
}
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());
session = 0;
return *this;
}
PluginData::~PluginData()
{
DeleteAll();
}
void PluginData::SetSession(Session * ses)
{
session = ses;
}
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()
{
bool all_null = true;
/*
when we copy a session's object (and this object then)
we resize the table and there are only null pointers there
consequently if all pointers are null there is no sens
to send WINIX_PLUGIN_SESSION_DATA_REMOVE
*/
for(size_t i=0 ; i<table.size() ; ++i)
{
if( table[i] != 0 )
{
all_null = false;
break;
}
}
/*
in the future this message may be removed
and we directly 'delete' the pointers
*/
if( !all_null )
plugin.Call(session, WINIX_PLUGIN_SESSION_DATA_REMOVE);
table.clear();
}
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;
}
} // namespace Winix

102
core/plugindata.h Executable file
View File

@@ -0,0 +1,102 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_plugindata
#define headerfile_winix_core_plugindata
#include <vector>
#include <cstddef>
namespace Winix
{
struct Session;
struct PluginDataBase
{
virtual ~PluginDataBase() {}
/*
!! CHECK ME
it is still in use?
when deleting sessions we first call Clear() method
consequently the destructor has nothing to do
(and it does not throw an exception)
*/
virtual void Clear() {}
};
class PluginData
{
public:
PluginData();
PluginData(const PluginData & p);
PluginData & operator=(const PluginData & p);
~PluginData();
void SetSession(Session * ses);
void Assign(size_t index, PluginDataBase * data);
void Assign(PluginDataBase * data);
PluginDataBase * Get(size_t index);
PluginDataBase * Get();
void DeleteAll();
size_t Size() const;
void Resize(size_t new_size);
private:
Session * session;
std::vector<PluginDataBase*> table;
};
} // namespace Winix
#endif

331
core/pluginmsg.h Executable file
View File

@@ -0,0 +1,331 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_pluginmsg
#define headerfile_winix_core_pluginmsg
namespace Winix
{
// here you can add your own EZC functions ([function])
// PluginInfo.p1 is a pointer to Ezc::Functions object
// session pointer is null
#define WINIX_TEMPLATES_CREATEFUNCTIONS 999
// here you can add your own EZC functions to notify system
// warning: this functions will be called from an other thread
// so you should use synchro->Lock() and synchro->Unlock()
// when attempting to winix objects
// PluginInfo.p1 is a pointer to Ezc::Functions object
// which is defined as:
// Ezc::Functions<NotifyStream> ezc_functions;
// and Notify Stream is:
// typedef TextStream<std::wstring> NotifyStream;
// session pointer is null
#define WINIX_NOTIFY_TEMPLATES_CREATEFUNCTIONS 998
// winix function and parameters have been parsed
// the request.status is OK
// (the winix function was not called yet)
#define WINIX_PREPARE_REQUEST 20000
// post and get functions have done their jobs
// now you can act
// this is called only if the request.status is OK
#define WINIX_PROCESS_REQUEST 20010
// prepere your content for displaying
// this is called after WINIX_PROCESS_REQUEST
// and when there is not a redirect
// request.status is not checked here
#define WINIX_CONTENT_MAKE 20020
// here you can attach your own session data (based on PluginDataBase class)
// call cur->session->plugin_data.Assign(pointer)
#define WINIX_SESSION_CREATED 30000
// here you should remove your session data
// this message can be sent even if you don't assing your plugin data
#define WINIX_PLUGIN_SESSION_DATA_REMOVE 30010
// when a session is changed (you can save a pointer to your data here)
// 'session changed' means that there is a new request
// !! IMPROVE ME it has to be changed to a better name
#define WINIX_SESSION_CHANGED 30020
// a session has changed its id
// it is typically when you are logging in
// 'login' winix function will change the session id (for security reasons)
// in l1 you have the old id, in l2 you have the new id
#define WINIX_SESSION_CHANGED_ID 30025
// a session is going to be removed
// it is called from session manager's thread (with lock/unlock)
#define WINIX_PREPARE_SESSION_TO_REMOVE 30027
// a session has been removed
// it is called from session manager's thread (with lock/unlock)
// in l1 you have the old session id
#define WINIX_SESSION_REMOVED 30029
// the winix is closing
// there is not any sessions available (cur->session is null)
// session pointer is null
#define WINIX_CLOSE 30040
// preparing to remove a file (rm function)
// in p1 you have a pointer to the Item struct (file)
// valid members are:
// id, parent_id, type, url, file_path, file_fs, file_type, has_thumb, hash, hash_type, file_size
// user_id, group_id, privileges
// (sometimes rest members can be valid as well -- when you call directly fun_rm->RemoveFileOrSymlink() method)
#define WINIX_FILE_PREPARE_TO_REMOVE 30045
// a file or symlink was removed (rm function)
// in p1 you have a pointer to the Item struct (old file)
// valid members are the same as in WINIX_FILE_PREPARE_TO_REMOVE
#define WINIX_FILE_REMOVED 30050
// preparing to remove a directory (rm function)
// in p1 you have a pointer to the Item struct (directory)
// this message is sent after checking the directory permissions
// so consequently if there is no any database error then the
// directory will be removed
// and after removed WINIX_DIR_REMOVED message is sent
#define WINIX_DIR_PREPARE_TO_REMOVE 30070
// directory was removed (rm function)
// PluginInfo::l1 is the directory id
#define WINIX_DIR_REMOVED 30060
// winix is initialized,
// now you can initialize your plugin
// session pointer is null
#define WINIX_PLUGIN_INIT 30080
// here you can add your own mount point, file systems, mount parameters
// for adding a new mount type call: system->mounts.AddMountType("new_mount_name")
// session pointer is null
#define WINIX_ADD_MOUNTS 30090
// add plugin functions (winix functions) here
// call info.functions->Add() to add a function
// session pointer is null
#define WINIX_CREATE_FUNCTIONS 30100
// choose a default function
// if you do not select it then it will be choosen by winix
#define WINIX_SELECT_DEFAULT_FUNCTION 30110
// /etc/fstab has been changed
// now we have new mount points
// session pointer is null
#define WINIX_FSTAB_CHANGED 30120
// here you add your own template to notification system
// call system->notify.AddTemplate() method
// with a template file name
// session pointer is null
#define WINIX_NOTIFY_ADD_TEMPLATE 30130
// the request is being ended
// you can clear some of your objects here
#define WINIX_END_REQUEST 30140
// a new file (page) has been added
// in p1 you have a pointer to the Item struct
#define WINIX_FILE_ADDED 30150
// a file (page) has been changed (edited)
// in p1 you have a pointer to the Item struct
#define WINIX_FILE_CHANGED 30160
// a new directory has been added
// in p1 you have a pointer to the Item struct
#define WINIX_DIR_ADDED 30155
// a file (page) has been copied
// in p1 you have a pointer to the Item struct
// not every fields of Item struct are filled
#define WINIX_FILE_COPIED 30170
// a file will be moved
// in p1 you have a pointer to the Item struct
// valid members are:
// id, parent_id, type, url, file_path, file_fs, file_type, has_thumb, hash, hash_type, file_size
// user_id, group_id, privileges, meta
// (sometimes rest members can be valid as well -- when you call directly fun_rm->RemoveFileOrSymlink() method)
#define WINIX_FILE_PREPARE_TO_MOVE 30180
// a file has been moved
// in p1 you have a pointer to the Item struct (new file)
// valid members are the same as in WINIX_FILE_PREPARE_TO_MOVE
#define WINIX_FILE_MOVED 30190
// a thumbnail was created
// this message is called from another thread
// the thread called Lock() before sending this message
// in p1 you have a pointer to the Item struct
// session pointer is null
#define WINIX_CREATED_THUMB 30500
// an image has been resized
// this message is called from another thread
// the thread called Lock() before sending this message
// in p1 you have a pointer to the Item struct
// session pointer is null
#define WINIX_IMAGE_RESIZED 30520
// content of a directory was sorted
// (winix 'sort' function was used)
// in p1 you have a pointer to the Item struct (of the directory)
// this is from system->dirs so you should not change the item
#define WINIX_DIR_CONTENT_SORTED 30500
// a user will be logged in
// set PluginInfo::res to false (it is by default) to prevent logging the user
// directly after this message (if you do not return false)
// a WINIX_USER_LOGGED is sent
// in p1 you have a pointer to User struct
// (if at least one plugin returns false then the user will not be logged)
// this message is not sent when winix starts and sessions are read from a sessions file
// in such a case only WINIX_USER_LOGGED will be sent
#define WINIX_PREPARE_USER_TO_LOGIN 30550
// a user has been logged
// send from 'login' winix function
// this message is also called when winix starts and reads sessions
// from the session file
#define WINIX_USER_LOGGED 30600
// a user is going to logout
// in p1 you have a pointer to User struct
// the message is also sent from the session GC (special thread for deleting sessions)
// in such a case is sent with Lock() and Unlock()
// so *don't* use Lock() in your procedure
#define WINIX_PREPARE_USER_TO_LOGOUT 30610
// here you add your own html templates
// call TemplatesFunctions::patterns.Add(L"file_name.html")
// the method returns an index which you have to remember
// and you can get the template with patterns.Get(index, lang_index)
// it returns a pointer to Ezc::Pattern (or null pointer if the index is wrong)
// the message will be sent too whenever 'reload/templates' winix function is called
// templates you should add only in this message
// in other cases after 'reload' function the indexes would be wrong
// session pointer is null
#define WINIX_ADD_TEMPLATE 31000
// a user will be removed
// in p1 you have a pointer to the User struct
// directly after this message a WINIX_USER_REMOVED will be sent
#define WINIX_PREPARE_TO_REMOVE_USER 31010
// a user has been removed
// in l1 you have the old user_id
#define WINIX_USER_REMOVED 31020
// here you can check if the domain part of the URL address is correct
// if no then set cur-request->redirect_to
// and winix will do a 'base url redirect' without making any winix functions
// the session pointer in info is null
#define WINIX_BASE_URL_REDIRECT 31030
// raw POST parameters
// in p1 there is a pointer to std::string meaning a parameter's name
// in p2 there is a pointer to std::string value
// this is sent only from PostParser
// PostMultiParser (multipart/form-data html forms) doesn't send this messsage
// there is no a session set (session pointer is null)
// this message is sent for each name value pairs
//
#define WINIX_POST_PARAMS 31040
// this is the raw string sent in POST method
// in p1 there is a pointer to std::string object
#define WINIX_RAW_POST_STRING 31050
// this message is sent before calling MakePost() or MakeGet()
// if you return false (which is default) you can prevent the access
// to the resource
#define WINIX_CHECK_PLUGIN_ACCESS 31060
// http headers (without cookies) were created and are ready to send
// here you can make some changes to them
// in p1 you have a pointer to the PT::Space (Request::out_headers)
#define WINIX_PREPARE_TO_SEND_HTTP_HEADERS 31070
// http cookies were created and are ready to send
// here you can make some changes to them
// in p1 you have a pointer to the PT::Space (Request::out_cookies)
#define WINIX_PREPARE_TO_SEND_HTTP_COOKIES 31080
/*
messages sent from other threads
!! IMPROVE ME check if some above messages should be moved here
*/
// a job has to be done
// this is sent from the other thread (without locking)
// in p1 you have a pointer to PT::Space
// session is null
// if you process the job then return 'true' from the processing method (from plugin call)
// so this prevent to make a standard (system) job
#define WINIX_JOB 31200
// values from 4000 - 4099 reserved for 'thread' plugin
// see plugins/thread/pluginmsg.h
// values from 4100 - 4199 reserved for 'ticket' plugin
// see plugins/ticket/pluginmsg.h
} // namespace Winix
#endif

624
core/postmultiparser.cpp Executable file
View File

@@ -0,0 +1,624 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <sys/types.h>
#include <unistd.h>
#include "postmultiparser.h"
#include "log.h"
#include "utf8/utf8.h"
namespace Winix
{
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)
{
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 << "): \"";
log.LogString(to_log, len);
log << "\"" << logend;
}
void PostMultiParser::ReadContentSkipBoundary(bool has_boundary)
{
if( has_boundary && content.size() >= boundary.size() )
{
content.erase(content.size()-boundary.size());
content_len -= boundary.size();
}
// the last new line character doesn't belong to the content
// this is a new line character before the boundary
if( !content.empty() && content[content.size()-1] == 10 )
{
content.erase(content.size()-1);
content_len -= 1;
if( line_end_dos && !content.empty() && content[content.size()-1] == 13 )
{
content.erase(content.size()-1);
content_len -= 1;
}
}
}
void PostMultiParser::ReadContentToFileLoop()
{
bool has_boundary = false;
while( last!=-1 )
{
content += last;
content_len += 1;
ReadChar();
if( HasBoundary() )
{
has_boundary = true;
break;
}
if( content.size() >= WINIX_POSTMULTI_OUTPUT_BUFFER )
{
tmp_file.write(content.c_str(), content.size());
content.clear();
}
if( config->post_file_max != 0 && content_len > 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.clear();
}
}
void PostMultiParser::ReadContentToFile()
{
time_t t1, t2;
content.clear();
content.reserve(WINIX_POSTMULTI_OUTPUT_BUFFER);
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;
if( !IsSubStringNoCase("pass", name.c_str()) )
LogFirst(content, config->log_post_value_size);
}
void PostMultiParser::ConvStr(const std::string & src, std::wstring & dst)
{
if( config->utf8 )
PT::UTF8ToWide(src, dst);
else
AssignString(src, dst);
}
void PostMultiParser::AddNormalPostVar()
{
if( post_tab->size() >= WINIX_POSTTABLE_MAXSIZE )
{
err = WINIX_ERR_INPUT_TOO_LARGE;
log << log1 << "PMP: more than " << WINIX_POSTTABLE_MAXSIZE << " post variables (skipping)" << logend;
return;
}
ConvStr(name, namew);
ConvStr(content, contentw);
bool added = InsertPostVar(*post_tab, namew, contentw);
log << log2 << "PMP: POST var, name: \"" << namew << "\"";
if( !added )
log << log2 << " (skipped)";
log << logend;
}
void PostMultiParser::AddFilePostVar()
{
if( post_file_tab->size() >= WINIX_POSTTABLE_MAXSIZE )
{
err = WINIX_ERR_INPUT_TOO_LARGE;
log << log1 << "PMP: more than " << WINIX_POSTTABLE_MAXSIZE << " post file variables (skipping)" << logend;
return;
}
ConvStr(name, namew);
ConvStr(filename, post_file_temp.filename);
post_file_temp.tmp_filename = tmp_filename;
post_file_temp.file_size = content_len;
bool added = InsertPostVar(*post_file_tab, namew, post_file_temp);
log << log2 << "PMP: POST FILE var, name: \"" << namew << "\"";
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()
{
wchar_t buf[1024];
size_t buf_len = sizeof(buf)/sizeof(wchar_t);
if( config->upload_dir.empty() )
{
log << log1 << "PMP: upload_dir is not set in the config" << logend;
err = WINIX_ERR_CANT_CREATE_FILE;
return;
}
swprintf(buf, buf_len, L"%ls/tmp/pmp_%u_%d_%u", config->upload_dir.c_str(), (unsigned)getpid(), tmp_filename_postfix, rand());
tmp_filename_postfix += 1;
tmp_filename = buf;
PT::WideToUTF8(tmp_filename, atmp_filename);
tmp_file.open(atmp_filename.c_str(), std::ios_base::binary | std::ios_base::out);
// !! dodac ustawienie chmod config.upload_files_chmod dla tymczasowego pliku
if( !tmp_file )
{
log << log1 << "PMP: can't create a temporary file: " << atmp_filename << logend;
err = WINIX_ERR_CANT_CREATE_FILE;
return;
}
log << log3 << "PMP: using temporary file for the content: " << atmp_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;
RemoveFile(tmp_filename);
}
}
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_, PostTab & post_tab_, PostFileTab & post_file_tab_)
{
in = in_;
last = 0;
err = WINIX_ERR_OK;
var_index = 1;
line_end_dos = false;
in_buffer_ind = WINIX_POSTMULTI_INPUT_BUFFER;
in_buffer_len = WINIX_POSTMULTI_INPUT_BUFFER;
post_tab = &post_tab_;
post_file_tab = &post_file_tab_;
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 )
{
RemovePostFileTmp(*post_file_tab);
post_tab->clear();
post_file_tab->clear();
if( err != WINIX_ERR_INPUT_TOO_LARGE && err != WINIX_ERR_CANT_CREATE_FILE )
log << log1 << "PMP: syntax error" << logend;
}
return err;
}
} // namespace Winix

165
core/postmultiparser.h Executable file
View File

@@ -0,0 +1,165 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_winix_core_postmultiparser
#define headerfile_winix_core_postmultiparser
#include <string>
#include <fcgiapp.h>
#include <fstream>
#include "error.h"
#include "requesttypes.h"
#include "config.h"
#include "misc.h"
namespace Winix
{
// 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_, PostTab & post_tab_, PostFileTab & post_file_tab_);
private:
Config * config;
FCGX_Stream * in;
unsigned char * in_buffer;
std::ofstream tmp_file;
std::wstring tmp_filename;
std::string atmp_filename;
int tmp_filename_postfix;
size_t in_buffer_ind;
size_t in_buffer_len;
PostTab * post_tab;
PostFileTab * post_file_tab;
int last; // last read character
int var_index; // used as a postfix to the same name (is auto increment)
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;
std::wstring namew, contentw;
PostFile post_file_temp;
void LogFirst(const std::string & to_log, size_t len);
void ConvStr(const std::string & src, std::wstring & dst);
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();
template<class Container, class Value>
bool InsertPostVar(Container & container, std::wstring & key, const Value & value);
};
template<class Container, class Value>
bool PostMultiParser::InsertPostVar(Container & container, std::wstring & key, const Value & value)
{
bool added;
std::pair<typename Container::iterator, bool> res;
res = container.insert( std::make_pair(key, value) );
added = res.second;
if( !added )
{
key += L"_inc";
key += Toa(var_index);
res = container.insert( std::make_pair(key, value) );
added = res.second;
var_index += 1;
}
return added;
}
} // namespace Winix
#endif

View File

@@ -1,56 +1,184 @@
/* /*
* This file is a part of CMSLU -- Content Management System like Unix * This file is a part of Winix
* and is not publicly distributed * and is distributed under the 2-Clause BSD licence.
* * Author: Tomasz Sowa <t.sowa@ttmath.org>
* Copyright (c) 2008, Tomasz Sowa */
/*
* Copyright (c) 2008-2014, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/ */
#ifndef headerfilepostparser #ifndef headerfile_winix_core_postparser
#define headerfilepostparser #define headerfile_winix_core_postparser
#include <fcgiapp.h> #include <fcgiapp.h>
#include <string> #include <string>
#include "httpsimpleparser.h" #include "httpsimpleparser.h"
#include "requesttypes.h" #include "requesttypes.h"
#include "misc.h"
#include "utf8/utf8.h"
#include "log.h"
#include "config.h"
#include "plugin.h"
namespace Winix
{
class PostParser : public HttpSimpleParser class PostParser : public HttpSimpleParser
{ {
FCGX_Stream * in; FCGX_Stream * in;
PostTable & post_table; PostTab * post_tab;
std::wstring temp_name, temp_value;
bool input_as_utf8;
size_t log_value_size;
int var_index;
bool has_winix_post_params_msg;
bool has_winix_raw_post_msg;
std::string raw_post;
protected: protected:
virtual int GetChar() virtual int GetChar()
{ {
return FCGX_GetChar(in); int c = FCGX_GetChar(in);
if( c != -1 && has_winix_raw_post_msg )
raw_post += c;
return c;
} }
virtual void Parameter(std::string & name, std::string & value) void CreateLog(bool param_added)
{ {
std::pair<PostTable::iterator, bool> res = post_table.insert( std::make_pair(name, value) ); log << log2 << "Method POST, name: \"" << temp_name << "\"";
log << log2 << "Method POST, name: \"" << name << "\", value: \"" << value << "\"";
if( res.second == false ) if( log_value_size > 0 && !IsSubStringNoCase(L"pass", temp_name.c_str()) )
{
log << ", value: ";
if( temp_value.size() > log_value_size )
log << "(first " << log_value_size << " characters) ";
log << "\"";
log.LogString(temp_value, log_value_size);
log << "\" (size: " << temp_value.size() << ")";
}
if( param_added == false )
log << log2 << " (skipped)"; log << log2 << " (skipped)";
log << log2 << logend; log << log2 << logend;
} }
void ConvStr(const std::string & src, std::wstring & dst)
{
if( input_as_utf8 )
PT::UTF8ToWide(src, dst);
else
AssignString(src, dst);
}
virtual void Parameter(std::string & name, std::string & value)
{
bool added;
std::pair<PostTab::iterator, bool> res;
if( has_winix_post_params_msg )
plugin.Call(0, WINIX_POST_PARAMS, &name, &value);
ConvStr(name, temp_name);
ConvStr(value, temp_value);
res = post_tab->insert( std::make_pair(temp_name, temp_value) );
added = res.second;
if( !added )
{
temp_name += L"_inc";
temp_name += Toa(var_index);
res = post_tab->insert( std::make_pair(temp_name, temp_value) );
added = res.second;
var_index += 1;
}
CreateLog(added);
}
public: public:
PostParser(FCGX_Stream * in_, PostTable & post_table_) : in(in_), post_table(post_table_) PostParser()
{ {
input_as_utf8 = false;
log_value_size = 0;
}
void UTF8(bool utf)
{
input_as_utf8 = utf;
}
void LogValueSize(size_t s)
{
log_value_size = s;
}
void Parse(FCGX_Stream * in_, PostTab & post_tab_)
{
in = in_;
post_tab = &post_tab_;
var_index = 1;
raw_post.clear();
has_winix_post_params_msg = plugin.HasMessage(WINIX_POST_PARAMS);
has_winix_raw_post_msg = plugin.HasMessage(WINIX_RAW_POST_STRING);
HttpSimpleParser::Parse();
if( has_winix_raw_post_msg )
plugin.Call(0, WINIX_RAW_POST_STRING, &raw_post);
raw_post.clear();
} }
}; };
} // namespace Winix
#endif #endif

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