58 Commits
0.4.0 ... 0.4.5

Author SHA1 Message Date
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
297 changed files with 22693 additions and 10886 deletions

View File

@@ -5,37 +5,44 @@ CXX = g++
endif
ifndef CXXFLAGS
#CXXFLAGS = -fPIC -Wall -pedantic -O2 -I/usr/local/include -I/home/tomek/roboczy/winix -I/home/tomek/roboczy/ezc/src -L/usr/local/lib -DEZC_USE_WINIX_LOGGER
CXXFLAGS = -fPIC -Wall -pedantic -O0 -g -I/usr/local/include -I/home/tomek/roboczy/winix -I/home/tomek/roboczy/ezc/src -L/usr/local/lib -DEZC_USE_WINIX_LOGGER
CXXFLAGS = -fPIC -Wall -pedantic -O2 -I/usr/local/include -I/home/tomek/roboczy/winix -I/home/tomek/roboczy/ezc/src -L/usr/local/lib -DEZC_USE_WINIX_LOGGER
endif
export CXX
export CXXFLAGS
all: winix
winix: FORCE
@cd core ; $(MAKE) -e
@cd db ; $(MAKE) -e
@cd functions ; $(MAKE) -e
@cd templates ; $(MAKE) -e
@cd templatesnotify ; $(MAKE) -e
@cd plugins/stats ; $(MAKE) -e
@cd notify ; $(MAKE) -e
@cd plugins/stats ; $(MAKE) -e
@cd plugins/ticket ; $(MAKE) -e
@cd ../ezc/src ; $(MAKE) -e
$(CXX) -shared -o winix.so $(CXXFLAGS) core/*.o functions/*.o templates/*.o templatesnotify/*.o ../ezc/src/ezc.a -lfcgi -lpq -lz -lpthread
$(CXX) -shared -o winix.so $(CXXFLAGS) core/*.o db/*.o functions/*.o templates/*.o notify/*.o ../ezc/src/ezc.a -lfcgi -lpq -lz -lpthread -lfetch
@cd main ; $(MAKE) -e
# use the full path with winix.so
$(CXX) -o winix $(CXXFLAGS) main/*.o /home/tomek/roboczy/winix/winix.so
clean:
@cd core ; $(MAKE) -e clean
@cd db ; $(MAKE) -e clean
@cd functions ; $(MAKE) -e clean
@cd templates ; $(MAKE) -e clean
@cd templatesnotify ; $(MAKE) -e clean
@cd plugins/stats ; $(MAKE) -e clean
@cd notify ; $(MAKE) -e clean
@cd plugins/stats ; $(MAKE) -e clean
@cd plugins/ticket ; $(MAKE) -e clean
@cd ../ezc/src ; $(MAKE) -e clean
@cd main ; $(MAKE) -e clean
rm -f winix.so
@@ -47,16 +54,36 @@ FORCE:
depend:
@cd core ; $(MAKE) -e depend
@cd db ; $(MAKE) -e depend
@cd functions ; $(MAKE) -e depend
@cd templates ; $(MAKE) -e depend
@cd templatesnotify ; $(MAKE) -e depend
@cd notify ; $(MAKE) -e depend
@cd plugins/stats ; $(MAKE) -e depend
@cd plugins/ticket ; $(MAKE) -e depend
@cd ../ezc/src ; $(MAKE) -e depend
@cd main ; $(MAKE) -e depend
#install: all
# mkdir -p bin
# rm -f bin/winix.so
# rm -f bin/winix
# cp winix.so bin/
# cp winix bin/
install: all
# binaries
mkdir -p /usr/local/winix/bin
cp winix.so /usr/local/winix/bin
# use the full path with winix.so (we have to recompile winix with a new path to winix.so)
$(CXX) -o /usr/local/winix/bin/winix $(CXXFLAGS) main/*.o /usr/local/winix/bin/winix.so
# html templates
mkdir -p /usr/local/winix/html
cp -rf html/ /usr/local/winix/html/
find /usr/local/winix/html/ -type d -name ".svn" | xargs -I foo rm -fr foo
# txt templates
mkdir -p /usr/local/winix/txt
cp -rf txt/ /usr/local/winix/txt/
find /usr/local/winix/txt/ -type d -name ".svn" | xargs -I foo rm -fr foo
# locales
mkdir -p /usr/local/winix/locale
cp -rf locale/ /usr/local/winix/locale/
find /usr/local/winix/locale/ -type d -name ".svn" | xargs -I foo rm -fr foo
# plugins
mkdir -p /usr/local/winix/plugins
find plugins/ -name "*.so" | xargs -I foo cp foo /usr/local/winix/plugins/
# removed provileges for others
find /usr/local/winix -exec chmod o-r,o-x,o-w "{}" "+"

View File

@@ -1 +0,0 @@
# DO NOT DELETE

View File

@@ -1 +0,0 @@
o =

View File

@@ -1,261 +1,406 @@
# DO NOT DELETE
Kopia config.o: ../core/log.h ../core/request.h requesttypes.h session.h
Kopia config.o: item.h error.h log.h user.h plugindata.h rebus.h thread.h
Kopia config.o: compress.h acceptencodingparser.h acceptbaseparser.h
Kopia config.o: htmlfilter.h postmultiparser.h config.h confparser.h ticket.h
Kopia config.o: ../core/config.h ../core/db.h group.h dircontainer.h
Kopia config.o: ugcontainer.h
acceptbaseparser.o: acceptbaseparser.h
app.o: app.h config.h confparser.h system.h dirs.h item.h dircontainer.h db.h
app.o: user.h group.h thread.h error.h log.h ugcontainer.h ticket.h request.h
app.o: requesttypes.h session.h plugindata.h rebus.h compress.h
app.o: acceptencodingparser.h acceptbaseparser.h htmlfilter.h
app.o: postmultiparser.h mounts.h mount.h users.h lastcontainer.h groups.h
app.o: loadavg.h sessionmanager.h sessioncontainer.h notify.h
app.o: ../templatesnotify/templatesnotify.h ../../ezc/src/ezc.h
app.o: ../core/mount.h ../core/locale.h ../core/config.h ../templates/misc.h
app.o: ../templates/localefilter.h ../core/locale.h ../functions/functions.h
app.o: ../functions/functionbase.h ../core/item.h ../core/db.h
app.o: ../core/request.h ../core/system.h ../core/notify.h
app.o: ../functions/functionparser.h ../functions/adduser.h
app.o: app.h config.h confparser.h htmlfilter.h system.h dirs.h item.h
app.o: dircontainer.h ../db/db.h ../db/dbbase.h ../db/dbconn.h
app.o: ../db/dbtextstream.h ../core/textstream.h misc.h ../core/error.h log.h
app.o: textstream.h ../db/dbitemquery.h ../core/item.h ../db/dbitemcolumns.h
app.o: ../core/user.h ../core/group.h ../core/thread.h ../core/dircontainer.h
app.o: ../core/ugcontainer.h request.h requesttypes.h session.h error.h
app.o: user.h plugindata.h rebus.h ../templates/htmltextstream.h
app.o: ../notify/notify.h ../notify/notifypool.h ../templates/locale.h
app.o: ../core/confparser.h ../templates/misc.h ../templates/localefilter.h
app.o: ../templates/locale.h ../../ezc/src/ezc.h ../../ezc/src/utf8.h
app.o: ../../ezc/src/generator.h ../../ezc/src/pattern.h
app.o: ../../ezc/src/functions.h ../../ezc/src/funinfo.h
app.o: ../../ezc/src/stringconv.h ../templates/htmltextstream.h
app.o: ../notify/notifythread.h ../core/basethread.h synchro.h
app.o: ../notify/templatesnotify.h ../core/config.h ../core/users.h
app.o: ugcontainer.h lastcontainer.h mounts.h mount.h mountparser.h users.h
app.o: groups.h group.h loadavg.h thumb.h basethread.h sessionmanager.h
app.o: sessioncontainer.h ../functions/functions.h
app.o: ../functions/functionbase.h ../core/request.h ../core/system.h
app.o: ../core/synchro.h ../functions/functionparser.h ../functions/adduser.h
app.o: ../functions/cat.h ../functions/chmod.h ../functions/privchanger.h
app.o: ../functions/chown.h ../functions/cp.h ../functions/createthread.h
app.o: ../functions/createticket.h ../functions/default.h
app.o: ../functions/download.h ../functions/editticket.h ../functions/emacs.h
app.o: ../functions/chown.h ../functions/ckeditor.h ../functions/cp.h
app.o: ../functions/createthread.h ../functions/functionbase.h
app.o: ../functions/default.h ../functions/download.h ../functions/emacs.h
app.o: ../functions/last.h ../functions/login.h ../functions/logout.h
app.o: ../functions/ls.h ../functions/mkdir.h ../functions/mv.h
app.o: ../functions/node.h ../functions/priv.h ../functions/reload.h
app.o: ../functions/rm.h ../functions/run.h ../functions/subject.h
app.o: ../functions/funthread.h ../core/thread.h ../functions/funticket.h
app.o: ../functions/uname.h ../functions/upload.h ../functions/who.h
app.o: ../templates/templates.h ../templates/patterncacher.h ../core/item.h
app.o: misc.h ../templates/ckeditorgetparser.h ../core/httpsimpleparser.h
app.o: ../core/log.h ../templates/indexpatterns.h ../core/sessionmanager.h
app.o: plugin.h pluginmsg.h
app.o: ../functions/ln.h ../functions/ls.h ../functions/mkdir.h
app.o: ../functions/mv.h ../functions/node.h ../functions/priv.h
app.o: ../functions/reload.h ../functions/rm.h ../functions/run.h
app.o: ../functions/specialdefault.h ../functions/stat.h
app.o: ../functions/subject.h ../functions/funthread.h
app.o: ../functions/template.h ../functions/tinymce.h ../functions/uname.h
app.o: ../functions/upload.h ../functions/uptime.h ../functions/who.h
app.o: ../functions/vim.h ../core/htmlfilter.h ../templates/templates.h
app.o: ../templates/patterncacher.h ../templates/ckeditorgetparser.h
app.o: ../core/httpsimpleparser.h ../core/log.h ../templates/indexpatterns.h
app.o: ../core/sessionmanager.h compress.h getparser.h httpsimpleparser.h
app.o: postparser.h cookieparser.h postmultiparser.h acceptencodingparser.h
app.o: acceptbaseparser.h plugin.h pluginmsg.h
basethread.o: basethread.h log.h textstream.h
bbcodeparser.o: bbcodeparser.h htmlfilter.h
compress.o: compress.h log.h
config.o: config.h confparser.h log.h plugin.h pluginmsg.h plugindata.h
config.o: request.h requesttypes.h session.h item.h error.h user.h rebus.h
config.o: thread.h compress.h acceptencodingparser.h acceptbaseparser.h
config.o: htmlfilter.h postmultiparser.h ticket.h system.h dirs.h
config.o: dircontainer.h db.h group.h ugcontainer.h mounts.h mount.h users.h
config.o: lastcontainer.h groups.h loadavg.h sessionmanager.h
config.o: sessioncontainer.h ../functions/functions.h
config.o: ../functions/functionbase.h ../core/item.h ../core/db.h
config.o: ../core/request.h ../core/config.h ../core/system.h
config.o: ../core/notify.h ../../ezc/src/ezc.h ../functions/functionparser.h
config.o: ../functions/adduser.h ../functions/cat.h ../functions/chmod.h
config.o: ../functions/privchanger.h ../functions/chown.h ../functions/cp.h
config.o: ../functions/createthread.h ../functions/createticket.h
config.o: ../functions/default.h ../functions/download.h
config.o: ../functions/editticket.h ../functions/emacs.h ../functions/last.h
config.o: ../functions/login.h ../functions/logout.h ../functions/ls.h
config.o: ../functions/mkdir.h ../functions/mv.h ../functions/node.h
config.o: ../functions/priv.h ../functions/reload.h ../functions/rm.h
config.o: ../functions/run.h ../functions/subject.h ../functions/funthread.h
config.o: ../core/thread.h ../functions/funticket.h ../functions/uname.h
config.o: ../functions/upload.h ../functions/who.h ../templates/templates.h
config.o: ../templates/patterncacher.h ../core/item.h misc.h
config.o: ../templates/ckeditorgetparser.h ../core/httpsimpleparser.h
config.o: ../core/log.h ../templates/indexpatterns.h
config.o: ../templates/localefilter.h ../core/locale.h ../core/locale.h
config.o: ../core/sessionmanager.h
confparser.o: confparser.h misc.h item.h
db.o: db.h item.h user.h group.h thread.h error.h log.h dircontainer.h
db.o: ugcontainer.h ticket.h misc.h
db_itemcolumns.o: db.h item.h user.h group.h thread.h error.h log.h
db_itemcolumns.o: dircontainer.h ugcontainer.h ticket.h
dircontainer.o: dircontainer.h item.h log.h
dirs.o: dirs.h item.h dircontainer.h db.h user.h group.h thread.h error.h
dirs.o: log.h ugcontainer.h ticket.h request.h requesttypes.h session.h
dirs.o: plugindata.h rebus.h compress.h acceptencodingparser.h
dirs.o: acceptbaseparser.h htmlfilter.h postmultiparser.h config.h
dirs.o: confparser.h
groups.o: groups.h group.h ugcontainer.h log.h db.h item.h user.h thread.h
groups.o: error.h dircontainer.h ticket.h
compress.o: compress.h log.h textstream.h
config.o: config.h confparser.h htmlfilter.h log.h textstream.h plugin.h
config.o: pluginmsg.h plugindata.h request.h requesttypes.h session.h item.h
config.o: error.h user.h rebus.h ../templates/htmltextstream.h
config.o: ../core/textstream.h misc.h system.h dirs.h dircontainer.h
config.o: ../db/db.h ../db/dbbase.h ../db/dbconn.h ../db/dbtextstream.h
config.o: ../core/error.h ../db/dbitemquery.h ../core/item.h
config.o: ../db/dbitemcolumns.h ../core/user.h ../core/group.h
config.o: ../core/thread.h ../core/dircontainer.h ../core/ugcontainer.h
config.o: ../notify/notify.h ../notify/notifypool.h ../templates/locale.h
config.o: ../core/confparser.h ../templates/misc.h
config.o: ../templates/localefilter.h ../templates/locale.h
config.o: ../../ezc/src/ezc.h ../../ezc/src/utf8.h ../../ezc/src/generator.h
config.o: ../../ezc/src/pattern.h ../../ezc/src/functions.h
config.o: ../../ezc/src/funinfo.h ../../ezc/src/stringconv.h
config.o: ../templates/htmltextstream.h ../notify/notifythread.h
config.o: ../core/basethread.h synchro.h ../notify/templatesnotify.h
config.o: ../core/config.h ../core/users.h ugcontainer.h lastcontainer.h
config.o: mounts.h mount.h mountparser.h users.h groups.h group.h loadavg.h
config.o: thumb.h basethread.h sessionmanager.h sessioncontainer.h
config.o: ../functions/functions.h ../functions/functionbase.h
config.o: ../core/request.h ../core/system.h ../core/synchro.h
config.o: ../functions/functionparser.h ../functions/adduser.h
config.o: ../functions/cat.h ../functions/chmod.h ../functions/privchanger.h
config.o: ../functions/chown.h ../functions/ckeditor.h ../functions/cp.h
config.o: ../functions/createthread.h ../functions/functionbase.h
config.o: ../functions/default.h ../functions/download.h ../functions/emacs.h
config.o: ../functions/last.h ../functions/login.h ../functions/logout.h
config.o: ../functions/ln.h ../functions/ls.h ../functions/mkdir.h
config.o: ../functions/mv.h ../functions/node.h ../functions/priv.h
config.o: ../functions/reload.h ../functions/rm.h ../functions/run.h
config.o: ../functions/specialdefault.h ../functions/stat.h
config.o: ../functions/subject.h ../functions/funthread.h
config.o: ../functions/template.h ../functions/tinymce.h ../functions/uname.h
config.o: ../functions/upload.h ../functions/uptime.h ../functions/who.h
config.o: ../functions/vim.h ../core/htmlfilter.h ../templates/templates.h
config.o: ../templates/patterncacher.h ../templates/ckeditorgetparser.h
config.o: ../core/httpsimpleparser.h ../core/log.h
config.o: ../templates/indexpatterns.h ../core/sessionmanager.h
confparser.o: confparser.h misc.h item.h ../../ezc/src/utf8.h
dircontainer.o: dircontainer.h item.h log.h textstream.h
dirs.o: dirs.h item.h dircontainer.h ../db/db.h ../db/dbbase.h ../db/dbconn.h
dirs.o: ../db/dbtextstream.h ../core/textstream.h misc.h ../core/error.h
dirs.o: log.h textstream.h ../db/dbitemquery.h ../core/item.h
dirs.o: ../db/dbitemcolumns.h ../core/user.h ../core/group.h ../core/thread.h
dirs.o: ../core/dircontainer.h ../core/ugcontainer.h request.h requesttypes.h
dirs.o: session.h error.h user.h plugindata.h rebus.h config.h confparser.h
dirs.o: htmlfilter.h ../templates/htmltextstream.h ../notify/notify.h
dirs.o: ../notify/notifypool.h ../templates/locale.h ../core/confparser.h
dirs.o: ../templates/misc.h ../templates/localefilter.h ../templates/locale.h
dirs.o: ../../ezc/src/ezc.h ../../ezc/src/utf8.h ../../ezc/src/generator.h
dirs.o: ../../ezc/src/pattern.h ../../ezc/src/functions.h
dirs.o: ../../ezc/src/funinfo.h ../../ezc/src/stringconv.h
dirs.o: ../templates/htmltextstream.h ../notify/notifythread.h
dirs.o: ../core/basethread.h synchro.h ../notify/templatesnotify.h
dirs.o: ../core/config.h ../core/users.h ugcontainer.h lastcontainer.h
groups.o: groups.h group.h ugcontainer.h ../db/db.h ../db/dbbase.h
groups.o: ../db/dbconn.h ../db/dbtextstream.h ../core/textstream.h misc.h
groups.o: item.h ../core/error.h log.h textstream.h ../db/dbitemquery.h
groups.o: ../core/item.h ../db/dbitemcolumns.h ../core/user.h ../core/group.h
groups.o: ../core/thread.h ../core/dircontainer.h ../core/ugcontainer.h
htmlfilter.o: htmlfilter.h
httpsimpleparser.o: httpsimpleparser.h
lastcontainer.o: lastcontainer.h log.h
loadavg.o: loadavg.h log.h
locale.o: locale.h confparser.h log.h
log.o: log.h
misc.o: misc.h item.h log.h
mount.o: mount.h
mountparser.o: mountparser.h mount.h item.h error.h log.h dirs.h
mountparser.o: dircontainer.h db.h user.h group.h thread.h ugcontainer.h
mountparser.o: ticket.h request.h requesttypes.h session.h plugindata.h
mountparser.o: rebus.h compress.h acceptencodingparser.h acceptbaseparser.h
mountparser.o: htmlfilter.h postmultiparser.h config.h confparser.h misc.h
mounts.o: mounts.h mount.h error.h log.h dirs.h item.h dircontainer.h db.h
mounts.o: user.h group.h thread.h ugcontainer.h ticket.h request.h
mounts.o: requesttypes.h session.h plugindata.h rebus.h compress.h
mounts.o: acceptencodingparser.h acceptbaseparser.h htmlfilter.h
mounts.o: postmultiparser.h config.h confparser.h mountparser.h
notify.o: log.h notify.h ../templatesnotify/templatesnotify.h
notify.o: ../../ezc/src/ezc.h ../core/mount.h ../core/locale.h confparser.h
notify.o: ../core/config.h ../templates/misc.h ../templates/localefilter.h
notify.o: ../core/locale.h request.h requesttypes.h session.h item.h error.h
notify.o: user.h plugindata.h rebus.h thread.h compress.h
notify.o: acceptencodingparser.h acceptbaseparser.h htmlfilter.h
notify.o: postmultiparser.h config.h ticket.h system.h dirs.h dircontainer.h
notify.o: db.h group.h ugcontainer.h mounts.h mount.h users.h lastcontainer.h
notify.o: groups.h loadavg.h misc.h
plugin.o: plugin.h pluginmsg.h log.h plugindata.h config.h confparser.h
plugin.o: request.h requesttypes.h session.h item.h error.h user.h rebus.h
plugin.o: thread.h compress.h acceptencodingparser.h acceptbaseparser.h
plugin.o: htmlfilter.h postmultiparser.h ticket.h system.h dirs.h
plugin.o: dircontainer.h db.h group.h ugcontainer.h mounts.h mount.h users.h
plugin.o: lastcontainer.h groups.h loadavg.h sessionmanager.h
plugin.o: sessioncontainer.h ../functions/functions.h
plugin.o: ../functions/functionbase.h ../core/item.h ../core/db.h
plugin.o: ../core/request.h ../core/config.h ../core/system.h
plugin.o: ../core/notify.h ../../ezc/src/ezc.h ../functions/functionparser.h
plugin.o: ../functions/adduser.h ../functions/cat.h ../functions/chmod.h
plugin.o: ../functions/privchanger.h ../functions/chown.h ../functions/cp.h
plugin.o: ../functions/createthread.h ../functions/createticket.h
plugin.o: ../functions/default.h ../functions/download.h
plugin.o: ../functions/editticket.h ../functions/emacs.h ../functions/last.h
plugin.o: ../functions/login.h ../functions/logout.h ../functions/ls.h
plugin.o: ../functions/mkdir.h ../functions/mv.h ../functions/node.h
plugin.o: ../functions/priv.h ../functions/reload.h ../functions/rm.h
plugin.o: ../functions/run.h ../functions/subject.h ../functions/funthread.h
plugin.o: ../core/thread.h ../functions/funticket.h ../functions/uname.h
plugin.o: ../functions/upload.h ../functions/who.h ../templates/templates.h
plugin.o: ../templates/patterncacher.h ../core/item.h misc.h
plugin.o: ../templates/ckeditorgetparser.h ../core/httpsimpleparser.h
plugin.o: ../core/log.h ../templates/indexpatterns.h
plugin.o: ../templates/localefilter.h ../core/locale.h ../core/locale.h
plugin.o: ../core/sessionmanager.h
plugindata.o: plugindata.h plugin.h pluginmsg.h log.h config.h confparser.h
plugindata.o: request.h requesttypes.h session.h item.h error.h user.h
plugindata.o: rebus.h thread.h compress.h acceptencodingparser.h
plugindata.o: acceptbaseparser.h htmlfilter.h postmultiparser.h ticket.h
plugindata.o: system.h dirs.h dircontainer.h db.h group.h ugcontainer.h
plugindata.o: mounts.h mount.h users.h lastcontainer.h groups.h loadavg.h
item.o: item.h misc.h
lastcontainer.o: lastcontainer.h log.h textstream.h misc.h item.h
loadavg.o: loadavg.h log.h textstream.h
log.o: log.h textstream.h ../../ezc/src/utf8.h
misc.o: misc.h item.h log.h textstream.h ../templates/templates.h
misc.o: ../../ezc/src/ezc.h ../../ezc/src/utf8.h ../../ezc/src/generator.h
misc.o: ../../ezc/src/pattern.h ../../ezc/src/functions.h
misc.o: ../../ezc/src/funinfo.h ../../ezc/src/stringconv.h
misc.o: ../templates/patterncacher.h ../core/item.h
misc.o: ../templates/ckeditorgetparser.h ../core/httpsimpleparser.h
misc.o: ../core/log.h ../templates/indexpatterns.h
misc.o: ../templates/localefilter.h ../templates/locale.h ../core/config.h
misc.o: ../db/db.h ../db/dbbase.h ../db/dbconn.h ../db/dbtextstream.h
misc.o: ../core/textstream.h ../core/error.h ../db/dbitemquery.h
misc.o: ../db/dbitemcolumns.h ../core/user.h ../core/group.h ../core/thread.h
misc.o: ../core/dircontainer.h ../core/ugcontainer.h
misc.o: ../templates/htmltextstream.h ../core/request.h ../core/system.h
misc.o: ../core/sessionmanager.h
mount.o: mount.h misc.h item.h
mountparser.o: mountparser.h mount.h item.h error.h dirs.h dircontainer.h
mountparser.o: ../db/db.h ../db/dbbase.h ../db/dbconn.h ../db/dbtextstream.h
mountparser.o: ../core/textstream.h misc.h ../core/error.h log.h textstream.h
mountparser.o: ../db/dbitemquery.h ../core/item.h ../db/dbitemcolumns.h
mountparser.o: ../core/user.h ../core/group.h ../core/thread.h
mountparser.o: ../core/dircontainer.h ../core/ugcontainer.h request.h
mountparser.o: requesttypes.h session.h user.h plugindata.h rebus.h config.h
mountparser.o: confparser.h htmlfilter.h ../templates/htmltextstream.h
mountparser.o: ../notify/notify.h ../notify/notifypool.h
mountparser.o: ../templates/locale.h ../core/confparser.h ../templates/misc.h
mountparser.o: ../templates/localefilter.h ../templates/locale.h
mountparser.o: ../../ezc/src/ezc.h ../../ezc/src/utf8.h
mountparser.o: ../../ezc/src/generator.h ../../ezc/src/pattern.h
mountparser.o: ../../ezc/src/functions.h ../../ezc/src/funinfo.h
mountparser.o: ../../ezc/src/stringconv.h ../templates/htmltextstream.h
mountparser.o: ../notify/notifythread.h ../core/basethread.h synchro.h
mountparser.o: ../notify/templatesnotify.h ../core/config.h ../core/users.h
mountparser.o: ugcontainer.h lastcontainer.h
mounts.o: mounts.h mount.h error.h dirs.h item.h dircontainer.h ../db/db.h
mounts.o: ../db/dbbase.h ../db/dbconn.h ../db/dbtextstream.h
mounts.o: ../core/textstream.h misc.h ../core/error.h log.h textstream.h
mounts.o: ../db/dbitemquery.h ../core/item.h ../db/dbitemcolumns.h
mounts.o: ../core/user.h ../core/group.h ../core/thread.h
mounts.o: ../core/dircontainer.h ../core/ugcontainer.h request.h
mounts.o: requesttypes.h session.h user.h plugindata.h rebus.h config.h
mounts.o: confparser.h htmlfilter.h ../templates/htmltextstream.h
mounts.o: ../notify/notify.h ../notify/notifypool.h ../templates/locale.h
mounts.o: ../core/confparser.h ../templates/misc.h
mounts.o: ../templates/localefilter.h ../templates/locale.h
mounts.o: ../../ezc/src/ezc.h ../../ezc/src/utf8.h ../../ezc/src/generator.h
mounts.o: ../../ezc/src/pattern.h ../../ezc/src/functions.h
mounts.o: ../../ezc/src/funinfo.h ../../ezc/src/stringconv.h
mounts.o: ../templates/htmltextstream.h ../notify/notifythread.h
mounts.o: ../core/basethread.h synchro.h ../notify/templatesnotify.h
mounts.o: ../core/config.h ../core/users.h ugcontainer.h lastcontainer.h
mounts.o: mountparser.h plugin.h pluginmsg.h system.h users.h groups.h
mounts.o: group.h loadavg.h thumb.h basethread.h sessionmanager.h
mounts.o: sessioncontainer.h ../functions/functions.h
mounts.o: ../functions/functionbase.h ../core/request.h ../core/system.h
mounts.o: ../core/synchro.h ../functions/functionparser.h
mounts.o: ../functions/adduser.h ../functions/cat.h ../functions/chmod.h
mounts.o: ../functions/privchanger.h ../functions/chown.h
mounts.o: ../functions/ckeditor.h ../functions/cp.h
mounts.o: ../functions/createthread.h ../functions/functionbase.h
mounts.o: ../functions/default.h ../functions/download.h ../functions/emacs.h
mounts.o: ../functions/last.h ../functions/login.h ../functions/logout.h
mounts.o: ../functions/ln.h ../functions/ls.h ../functions/mkdir.h
mounts.o: ../functions/mv.h ../functions/node.h ../functions/priv.h
mounts.o: ../functions/reload.h ../functions/rm.h ../functions/run.h
mounts.o: ../functions/specialdefault.h ../functions/stat.h
mounts.o: ../functions/subject.h ../functions/funthread.h
mounts.o: ../functions/template.h ../functions/tinymce.h ../functions/uname.h
mounts.o: ../functions/upload.h ../functions/uptime.h ../functions/who.h
mounts.o: ../functions/vim.h ../core/htmlfilter.h ../templates/templates.h
mounts.o: ../templates/patterncacher.h ../templates/ckeditorgetparser.h
mounts.o: ../core/httpsimpleparser.h ../core/log.h
mounts.o: ../templates/indexpatterns.h ../core/sessionmanager.h
plugin.o: plugin.h pluginmsg.h log.h textstream.h plugindata.h config.h
plugin.o: confparser.h htmlfilter.h request.h requesttypes.h session.h item.h
plugin.o: error.h user.h rebus.h ../templates/htmltextstream.h
plugin.o: ../core/textstream.h misc.h system.h dirs.h dircontainer.h
plugin.o: ../db/db.h ../db/dbbase.h ../db/dbconn.h ../db/dbtextstream.h
plugin.o: ../core/error.h ../db/dbitemquery.h ../core/item.h
plugin.o: ../db/dbitemcolumns.h ../core/user.h ../core/group.h
plugin.o: ../core/thread.h ../core/dircontainer.h ../core/ugcontainer.h
plugin.o: ../notify/notify.h ../notify/notifypool.h ../templates/locale.h
plugin.o: ../core/confparser.h ../templates/misc.h
plugin.o: ../templates/localefilter.h ../templates/locale.h
plugin.o: ../../ezc/src/ezc.h ../../ezc/src/utf8.h ../../ezc/src/generator.h
plugin.o: ../../ezc/src/pattern.h ../../ezc/src/functions.h
plugin.o: ../../ezc/src/funinfo.h ../../ezc/src/stringconv.h
plugin.o: ../templates/htmltextstream.h ../notify/notifythread.h
plugin.o: ../core/basethread.h synchro.h ../notify/templatesnotify.h
plugin.o: ../core/config.h ../core/users.h ugcontainer.h lastcontainer.h
plugin.o: mounts.h mount.h mountparser.h users.h groups.h group.h loadavg.h
plugin.o: thumb.h basethread.h sessionmanager.h sessioncontainer.h
plugin.o: ../functions/functions.h ../functions/functionbase.h
plugin.o: ../core/request.h ../core/system.h ../core/synchro.h
plugin.o: ../functions/functionparser.h ../functions/adduser.h
plugin.o: ../functions/cat.h ../functions/chmod.h ../functions/privchanger.h
plugin.o: ../functions/chown.h ../functions/ckeditor.h ../functions/cp.h
plugin.o: ../functions/createthread.h ../functions/functionbase.h
plugin.o: ../functions/default.h ../functions/download.h ../functions/emacs.h
plugin.o: ../functions/last.h ../functions/login.h ../functions/logout.h
plugin.o: ../functions/ln.h ../functions/ls.h ../functions/mkdir.h
plugin.o: ../functions/mv.h ../functions/node.h ../functions/priv.h
plugin.o: ../functions/reload.h ../functions/rm.h ../functions/run.h
plugin.o: ../functions/specialdefault.h ../functions/stat.h
plugin.o: ../functions/subject.h ../functions/funthread.h
plugin.o: ../functions/template.h ../functions/tinymce.h ../functions/uname.h
plugin.o: ../functions/upload.h ../functions/uptime.h ../functions/who.h
plugin.o: ../functions/vim.h ../core/htmlfilter.h ../templates/templates.h
plugin.o: ../templates/patterncacher.h ../templates/ckeditorgetparser.h
plugin.o: ../core/httpsimpleparser.h ../core/log.h
plugin.o: ../templates/indexpatterns.h ../core/sessionmanager.h
plugindata.o: plugindata.h plugin.h pluginmsg.h log.h textstream.h config.h
plugindata.o: confparser.h htmlfilter.h request.h requesttypes.h session.h
plugindata.o: item.h error.h user.h rebus.h ../templates/htmltextstream.h
plugindata.o: ../core/textstream.h misc.h system.h dirs.h dircontainer.h
plugindata.o: ../db/db.h ../db/dbbase.h ../db/dbconn.h ../db/dbtextstream.h
plugindata.o: ../core/error.h ../db/dbitemquery.h ../core/item.h
plugindata.o: ../db/dbitemcolumns.h ../core/user.h ../core/group.h
plugindata.o: ../core/thread.h ../core/dircontainer.h ../core/ugcontainer.h
plugindata.o: ../notify/notify.h ../notify/notifypool.h ../templates/locale.h
plugindata.o: ../core/confparser.h ../templates/misc.h
plugindata.o: ../templates/localefilter.h ../templates/locale.h
plugindata.o: ../../ezc/src/ezc.h ../../ezc/src/utf8.h
plugindata.o: ../../ezc/src/generator.h ../../ezc/src/pattern.h
plugindata.o: ../../ezc/src/functions.h ../../ezc/src/funinfo.h
plugindata.o: ../../ezc/src/stringconv.h ../templates/htmltextstream.h
plugindata.o: ../notify/notifythread.h ../core/basethread.h synchro.h
plugindata.o: ../notify/templatesnotify.h ../core/config.h ../core/users.h
plugindata.o: ugcontainer.h lastcontainer.h mounts.h mount.h mountparser.h
plugindata.o: users.h groups.h group.h loadavg.h thumb.h basethread.h
plugindata.o: sessionmanager.h sessioncontainer.h ../functions/functions.h
plugindata.o: ../functions/functionbase.h ../core/item.h ../core/db.h
plugindata.o: ../core/request.h ../core/config.h ../core/system.h
plugindata.o: ../core/notify.h ../../ezc/src/ezc.h
plugindata.o: ../functions/functionparser.h ../functions/adduser.h
plugindata.o: ../functions/cat.h ../functions/chmod.h
plugindata.o: ../functions/functionbase.h ../core/request.h ../core/system.h
plugindata.o: ../core/synchro.h ../functions/functionparser.h
plugindata.o: ../functions/adduser.h ../functions/cat.h ../functions/chmod.h
plugindata.o: ../functions/privchanger.h ../functions/chown.h
plugindata.o: ../functions/cp.h ../functions/createthread.h
plugindata.o: ../functions/createticket.h ../functions/default.h
plugindata.o: ../functions/download.h ../functions/editticket.h
plugindata.o: ../functions/ckeditor.h ../functions/cp.h
plugindata.o: ../functions/createthread.h ../functions/functionbase.h
plugindata.o: ../functions/default.h ../functions/download.h
plugindata.o: ../functions/emacs.h ../functions/last.h ../functions/login.h
plugindata.o: ../functions/logout.h ../functions/ls.h ../functions/mkdir.h
plugindata.o: ../functions/mv.h ../functions/node.h ../functions/priv.h
plugindata.o: ../functions/reload.h ../functions/rm.h ../functions/run.h
plugindata.o: ../functions/subject.h ../functions/funthread.h
plugindata.o: ../core/thread.h ../functions/funticket.h ../functions/uname.h
plugindata.o: ../functions/upload.h ../functions/who.h
plugindata.o: ../functions/logout.h ../functions/ln.h ../functions/ls.h
plugindata.o: ../functions/mkdir.h ../functions/mv.h ../functions/node.h
plugindata.o: ../functions/priv.h ../functions/reload.h ../functions/rm.h
plugindata.o: ../functions/run.h ../functions/specialdefault.h
plugindata.o: ../functions/stat.h ../functions/subject.h
plugindata.o: ../functions/funthread.h ../functions/template.h
plugindata.o: ../functions/tinymce.h ../functions/uname.h
plugindata.o: ../functions/upload.h ../functions/uptime.h ../functions/who.h
plugindata.o: ../functions/vim.h ../core/htmlfilter.h
plugindata.o: ../templates/templates.h ../templates/patterncacher.h
plugindata.o: ../core/item.h misc.h ../templates/ckeditorgetparser.h
plugindata.o: ../core/httpsimpleparser.h ../core/log.h
plugindata.o: ../templates/indexpatterns.h ../templates/localefilter.h
plugindata.o: ../core/locale.h ../core/locale.h ../core/sessionmanager.h
postmultiparser.o: postmultiparser.h error.h log.h requesttypes.h config.h
postmultiparser.o: confparser.h
rebus.o: log.h rebus.h misc.h item.h request.h requesttypes.h session.h
rebus.o: error.h user.h plugindata.h thread.h compress.h
rebus.o: acceptencodingparser.h acceptbaseparser.h htmlfilter.h
rebus.o: postmultiparser.h config.h confparser.h ticket.h
request.o: request.h requesttypes.h session.h item.h error.h log.h user.h
request.o: plugindata.h rebus.h thread.h compress.h acceptencodingparser.h
request.o: acceptbaseparser.h htmlfilter.h postmultiparser.h config.h
request.o: confparser.h ticket.h getparser.h httpsimpleparser.h postparser.h
request.o: cookieparser.h plugin.h pluginmsg.h system.h dirs.h dircontainer.h
request.o: db.h group.h ugcontainer.h mounts.h mount.h users.h
request.o: lastcontainer.h groups.h loadavg.h sessionmanager.h
request.o: sessioncontainer.h ../functions/functions.h
request.o: ../functions/functionbase.h ../core/item.h ../core/db.h
request.o: ../core/request.h ../core/config.h ../core/system.h
request.o: ../core/notify.h ../../ezc/src/ezc.h ../functions/functionparser.h
request.o: ../functions/adduser.h ../functions/cat.h ../functions/chmod.h
request.o: ../functions/privchanger.h ../functions/chown.h ../functions/cp.h
request.o: ../functions/createthread.h ../functions/createticket.h
plugindata.o: ../templates/ckeditorgetparser.h ../core/httpsimpleparser.h
plugindata.o: ../core/log.h ../templates/indexpatterns.h
plugindata.o: ../core/sessionmanager.h
postmultiparser.o: postmultiparser.h error.h requesttypes.h config.h
postmultiparser.o: confparser.h htmlfilter.h log.h textstream.h
postmultiparser.o: ../../ezc/src/utf8.h misc.h item.h
rebus.o: log.h textstream.h rebus.h misc.h item.h request.h requesttypes.h
rebus.o: session.h error.h user.h plugindata.h config.h confparser.h
rebus.o: htmlfilter.h ../templates/htmltextstream.h ../core/textstream.h
request.o: request.h requesttypes.h session.h item.h error.h user.h
request.o: plugindata.h rebus.h config.h confparser.h htmlfilter.h
request.o: textstream.h ../templates/htmltextstream.h ../core/textstream.h
request.o: misc.h log.h plugin.h pluginmsg.h system.h dirs.h dircontainer.h
request.o: ../db/db.h ../db/dbbase.h ../db/dbconn.h ../db/dbtextstream.h
request.o: ../core/error.h ../db/dbitemquery.h ../core/item.h
request.o: ../db/dbitemcolumns.h ../core/user.h ../core/group.h
request.o: ../core/thread.h ../core/dircontainer.h ../core/ugcontainer.h
request.o: ../notify/notify.h ../notify/notifypool.h ../templates/locale.h
request.o: ../core/confparser.h ../templates/misc.h
request.o: ../templates/localefilter.h ../templates/locale.h
request.o: ../../ezc/src/ezc.h ../../ezc/src/utf8.h ../../ezc/src/generator.h
request.o: ../../ezc/src/pattern.h ../../ezc/src/functions.h
request.o: ../../ezc/src/funinfo.h ../../ezc/src/stringconv.h
request.o: ../templates/htmltextstream.h ../notify/notifythread.h
request.o: ../core/basethread.h synchro.h ../notify/templatesnotify.h
request.o: ../core/config.h ../core/users.h ugcontainer.h lastcontainer.h
request.o: mounts.h mount.h mountparser.h users.h groups.h group.h loadavg.h
request.o: thumb.h basethread.h sessionmanager.h sessioncontainer.h
request.o: ../functions/functions.h ../functions/functionbase.h
request.o: ../core/request.h ../core/system.h ../core/synchro.h
request.o: ../functions/functionparser.h ../functions/adduser.h
request.o: ../functions/cat.h ../functions/chmod.h ../functions/privchanger.h
request.o: ../functions/chown.h ../functions/ckeditor.h ../functions/cp.h
request.o: ../functions/createthread.h ../functions/functionbase.h
request.o: ../functions/default.h ../functions/download.h
request.o: ../functions/editticket.h ../functions/emacs.h ../functions/last.h
request.o: ../functions/login.h ../functions/logout.h ../functions/ls.h
request.o: ../functions/emacs.h ../functions/last.h ../functions/login.h
request.o: ../functions/logout.h ../functions/ln.h ../functions/ls.h
request.o: ../functions/mkdir.h ../functions/mv.h ../functions/node.h
request.o: ../functions/priv.h ../functions/reload.h ../functions/rm.h
request.o: ../functions/run.h ../functions/subject.h ../functions/funthread.h
request.o: ../core/thread.h ../functions/funticket.h ../functions/uname.h
request.o: ../functions/upload.h ../functions/who.h ../templates/templates.h
request.o: ../templates/patterncacher.h ../core/item.h misc.h
request.o: ../templates/ckeditorgetparser.h ../core/httpsimpleparser.h
request.o: ../core/log.h ../templates/indexpatterns.h
request.o: ../templates/localefilter.h ../core/locale.h ../core/locale.h
request.o: ../core/sessionmanager.h ../functions/functionbase.h
session.o: session.h item.h error.h log.h user.h plugindata.h rebus.h
sessioncontainer.o: sessioncontainer.h session.h item.h error.h log.h user.h
sessioncontainer.o: plugindata.h rebus.h lastcontainer.h
request.o: ../functions/run.h ../functions/specialdefault.h
request.o: ../functions/stat.h ../functions/subject.h
request.o: ../functions/funthread.h ../functions/template.h
request.o: ../functions/tinymce.h ../functions/uname.h ../functions/upload.h
request.o: ../functions/uptime.h ../functions/who.h ../functions/vim.h
request.o: ../core/htmlfilter.h ../templates/templates.h
request.o: ../templates/patterncacher.h ../templates/ckeditorgetparser.h
request.o: ../core/httpsimpleparser.h ../core/log.h
request.o: ../templates/indexpatterns.h ../core/sessionmanager.h
session.o: session.h item.h error.h user.h plugindata.h rebus.h misc.h
sessioncontainer.o: sessioncontainer.h session.h item.h error.h user.h
sessioncontainer.o: plugindata.h rebus.h lastcontainer.h request.h
sessioncontainer.o: requesttypes.h config.h confparser.h htmlfilter.h
sessioncontainer.o: textstream.h ../templates/htmltextstream.h
sessioncontainer.o: ../core/textstream.h misc.h basethread.h log.h
sessionmanager.o: sessionmanager.h sessioncontainer.h session.h item.h
sessionmanager.o: error.h log.h user.h plugindata.h rebus.h lastcontainer.h
sessionmanager.o: config.h confparser.h request.h requesttypes.h thread.h
sessionmanager.o: compress.h acceptencodingparser.h acceptbaseparser.h
sessionmanager.o: htmlfilter.h postmultiparser.h ticket.h system.h dirs.h
sessionmanager.o: dircontainer.h db.h group.h ugcontainer.h mounts.h mount.h
sessionmanager.o: users.h groups.h loadavg.h sessionparser.h plugin.h
sessionmanager.o: pluginmsg.h ../functions/functions.h
sessionmanager.o: ../functions/functionbase.h ../core/item.h ../core/db.h
sessionmanager.o: ../core/request.h ../core/config.h ../core/system.h
sessionmanager.o: ../core/notify.h ../../ezc/src/ezc.h
sessionmanager.o: error.h user.h plugindata.h rebus.h lastcontainer.h
sessionmanager.o: request.h requesttypes.h config.h confparser.h htmlfilter.h
sessionmanager.o: textstream.h ../templates/htmltextstream.h
sessionmanager.o: ../core/textstream.h misc.h basethread.h system.h dirs.h
sessionmanager.o: dircontainer.h ../db/db.h ../db/dbbase.h ../db/dbconn.h
sessionmanager.o: ../db/dbtextstream.h ../core/error.h log.h
sessionmanager.o: ../db/dbitemquery.h ../core/item.h ../db/dbitemcolumns.h
sessionmanager.o: ../core/user.h ../core/group.h ../core/thread.h
sessionmanager.o: ../core/dircontainer.h ../core/ugcontainer.h
sessionmanager.o: ../notify/notify.h ../notify/notifypool.h
sessionmanager.o: ../templates/locale.h ../core/confparser.h
sessionmanager.o: ../templates/misc.h ../templates/localefilter.h
sessionmanager.o: ../templates/locale.h ../../ezc/src/ezc.h
sessionmanager.o: ../../ezc/src/utf8.h ../../ezc/src/generator.h
sessionmanager.o: ../../ezc/src/pattern.h ../../ezc/src/functions.h
sessionmanager.o: ../../ezc/src/funinfo.h ../../ezc/src/stringconv.h
sessionmanager.o: ../templates/htmltextstream.h ../notify/notifythread.h
sessionmanager.o: ../core/basethread.h synchro.h ../notify/templatesnotify.h
sessionmanager.o: ../core/config.h ../core/users.h ugcontainer.h mounts.h
sessionmanager.o: mount.h mountparser.h users.h groups.h group.h loadavg.h
sessionmanager.o: thumb.h sessionparser.h plugin.h pluginmsg.h
sessionmanager.o: ../functions/functions.h ../functions/functionbase.h
sessionmanager.o: ../core/request.h ../core/system.h ../core/synchro.h
sessionmanager.o: ../functions/functionparser.h ../functions/adduser.h
sessionmanager.o: ../functions/cat.h ../functions/chmod.h
sessionmanager.o: ../functions/privchanger.h ../functions/chown.h
sessionmanager.o: ../functions/cp.h ../functions/createthread.h
sessionmanager.o: ../functions/createticket.h ../functions/default.h
sessionmanager.o: ../functions/download.h ../functions/editticket.h
sessionmanager.o: ../functions/ckeditor.h ../functions/cp.h
sessionmanager.o: ../functions/createthread.h ../functions/functionbase.h
sessionmanager.o: ../functions/default.h ../functions/download.h
sessionmanager.o: ../functions/emacs.h ../functions/last.h
sessionmanager.o: ../functions/login.h ../functions/logout.h
sessionmanager.o: ../functions/ls.h ../functions/mkdir.h ../functions/mv.h
sessionmanager.o: ../functions/node.h ../functions/priv.h
sessionmanager.o: ../functions/ln.h ../functions/ls.h ../functions/mkdir.h
sessionmanager.o: ../functions/mv.h ../functions/node.h ../functions/priv.h
sessionmanager.o: ../functions/reload.h ../functions/rm.h ../functions/run.h
sessionmanager.o: ../functions/specialdefault.h ../functions/stat.h
sessionmanager.o: ../functions/subject.h ../functions/funthread.h
sessionmanager.o: ../core/thread.h ../functions/funticket.h
sessionmanager.o: ../functions/template.h ../functions/tinymce.h
sessionmanager.o: ../functions/uname.h ../functions/upload.h
sessionmanager.o: ../functions/who.h ../templates/templates.h
sessionmanager.o: ../templates/patterncacher.h ../core/item.h misc.h
sessionmanager.o: ../functions/uptime.h ../functions/who.h ../functions/vim.h
sessionmanager.o: ../core/htmlfilter.h ../templates/templates.h
sessionmanager.o: ../templates/patterncacher.h
sessionmanager.o: ../templates/ckeditorgetparser.h ../core/httpsimpleparser.h
sessionmanager.o: ../core/log.h ../templates/indexpatterns.h
sessionmanager.o: ../templates/localefilter.h ../core/locale.h
sessionmanager.o: ../core/locale.h ../core/sessionmanager.h
sessionparser.o: sessionparser.h session.h item.h error.h log.h user.h
sessionparser.o: plugindata.h rebus.h sessioncontainer.h lastcontainer.h
sessionparser.o: users.h ugcontainer.h request.h requesttypes.h thread.h
sessionparser.o: compress.h acceptencodingparser.h acceptbaseparser.h
sessionparser.o: htmlfilter.h postmultiparser.h config.h confparser.h
sessionparser.o: ticket.h db.h group.h dircontainer.h
system.o: system.h dirs.h item.h dircontainer.h db.h user.h group.h thread.h
system.o: error.h log.h ugcontainer.h ticket.h request.h requesttypes.h
system.o: session.h plugindata.h rebus.h compress.h acceptencodingparser.h
system.o: acceptbaseparser.h htmlfilter.h postmultiparser.h config.h
system.o: confparser.h mounts.h mount.h users.h lastcontainer.h groups.h
system.o: loadavg.h misc.h notify.h ../templatesnotify/templatesnotify.h
system.o: ../../ezc/src/ezc.h ../core/mount.h ../core/locale.h
system.o: ../core/config.h ../templates/misc.h ../templates/localefilter.h
system.o: ../core/locale.h ../functions/functions.h
system.o: ../functions/functionbase.h ../core/item.h ../core/db.h
system.o: ../core/request.h ../core/system.h ../core/notify.h
system.o: ../functions/functionparser.h ../functions/adduser.h
system.o: ../functions/cat.h ../functions/chmod.h ../functions/privchanger.h
system.o: ../functions/chown.h ../functions/cp.h ../functions/createthread.h
system.o: ../functions/createticket.h ../functions/default.h
system.o: ../functions/download.h ../functions/editticket.h
system.o: ../functions/emacs.h ../functions/last.h ../functions/login.h
system.o: ../functions/logout.h ../functions/ls.h ../functions/mkdir.h
system.o: ../functions/mv.h ../functions/node.h ../functions/priv.h
system.o: ../functions/reload.h ../functions/rm.h ../functions/run.h
system.o: ../functions/subject.h ../functions/funthread.h ../core/thread.h
system.o: ../functions/funticket.h ../functions/uname.h ../functions/upload.h
system.o: ../functions/who.h ../templates/templates.h
system.o: ../templates/patterncacher.h ../core/item.h
sessionmanager.o: ../core/sessionmanager.h
sessionparser.o: sessionparser.h session.h item.h error.h user.h plugindata.h
sessionparser.o: rebus.h sessioncontainer.h lastcontainer.h request.h
sessionparser.o: requesttypes.h config.h confparser.h htmlfilter.h
sessionparser.o: textstream.h ../templates/htmltextstream.h
sessionparser.o: ../core/textstream.h misc.h basethread.h users.h log.h
synchro.o: synchro.h
system.o: system.h dirs.h item.h dircontainer.h ../db/db.h ../db/dbbase.h
system.o: ../db/dbconn.h ../db/dbtextstream.h ../core/textstream.h misc.h
system.o: ../core/error.h log.h textstream.h ../db/dbitemquery.h
system.o: ../core/item.h ../db/dbitemcolumns.h ../core/user.h ../core/group.h
system.o: ../core/thread.h ../core/dircontainer.h ../core/ugcontainer.h
system.o: request.h requesttypes.h session.h error.h user.h plugindata.h
system.o: rebus.h config.h confparser.h htmlfilter.h
system.o: ../templates/htmltextstream.h ../notify/notify.h
system.o: ../notify/notifypool.h ../templates/locale.h ../core/confparser.h
system.o: ../templates/misc.h ../templates/localefilter.h
system.o: ../templates/locale.h ../../ezc/src/ezc.h ../../ezc/src/utf8.h
system.o: ../../ezc/src/generator.h ../../ezc/src/pattern.h
system.o: ../../ezc/src/functions.h ../../ezc/src/funinfo.h
system.o: ../../ezc/src/stringconv.h ../templates/htmltextstream.h
system.o: ../notify/notifythread.h ../core/basethread.h synchro.h
system.o: ../notify/templatesnotify.h ../core/config.h ../core/users.h
system.o: ugcontainer.h lastcontainer.h mounts.h mount.h mountparser.h
system.o: users.h groups.h group.h loadavg.h thumb.h basethread.h
system.o: ../templates/templates.h ../templates/patterncacher.h
system.o: ../templates/ckeditorgetparser.h ../core/httpsimpleparser.h
system.o: ../core/log.h ../templates/indexpatterns.h ../core/sessionmanager.h
users.o: users.h user.h ugcontainer.h log.h lastcontainer.h request.h
users.o: requesttypes.h session.h item.h error.h plugindata.h rebus.h
users.o: thread.h compress.h acceptencodingparser.h acceptbaseparser.h
users.o: htmlfilter.h postmultiparser.h config.h confparser.h ticket.h db.h
users.o: group.h dircontainer.h
system.o: ../core/log.h ../templates/indexpatterns.h ../core/request.h
system.o: ../core/system.h ../core/sessionmanager.h
system.o: ../functions/functionbase.h
textstream.o: textstream.h misc.h item.h
thumb.o: thumb.h basethread.h textstream.h ../db/db.h ../db/dbbase.h
thumb.o: ../db/dbconn.h ../db/dbtextstream.h ../core/textstream.h misc.h
thumb.o: item.h ../core/error.h log.h ../db/dbitemquery.h ../core/item.h
thumb.o: ../db/dbitemcolumns.h ../core/user.h ../core/group.h
thumb.o: ../core/thread.h ../core/dircontainer.h ../core/ugcontainer.h
thumb.o: ../core/config.h ../../ezc/src/utf8.h system.h dirs.h dircontainer.h
thumb.o: request.h requesttypes.h session.h error.h user.h plugindata.h
thumb.o: rebus.h config.h confparser.h htmlfilter.h
thumb.o: ../templates/htmltextstream.h ../notify/notify.h
thumb.o: ../notify/notifypool.h ../templates/locale.h ../core/confparser.h
thumb.o: ../templates/misc.h ../templates/localefilter.h
thumb.o: ../templates/locale.h ../../ezc/src/ezc.h ../../ezc/src/generator.h
thumb.o: ../../ezc/src/pattern.h ../../ezc/src/functions.h
thumb.o: ../../ezc/src/funinfo.h ../../ezc/src/stringconv.h
thumb.o: ../templates/htmltextstream.h ../notify/notifythread.h
thumb.o: ../core/basethread.h synchro.h ../notify/templatesnotify.h
thumb.o: ../core/users.h ugcontainer.h lastcontainer.h mounts.h mount.h
thumb.o: mountparser.h users.h groups.h group.h loadavg.h
users.o: users.h

View File

@@ -1 +1 @@
o = Kopia config.o acceptbaseparser.o app.o bbcodeparser.o compress.o config.o confparser.o db.o db_itemcolumns.o dircontainer.o dirs.o groups.o htmlfilter.o httpsimpleparser.o lastcontainer.o loadavg.o locale.o log.o misc.o mount.o mountparser.o mounts.o notify.o plugin.o plugindata.o postmultiparser.o rebus.o request.o session.o sessioncontainer.o sessionmanager.o sessionparser.o system.o users.o
o = acceptbaseparser.o app.o basethread.o bbcodeparser.o compress.o config.o confparser.o dircontainer.o dirs.o groups.o htmlfilter.o httpsimpleparser.o item.o lastcontainer.o loadavg.o log.o misc.o mount.o mountparser.o mounts.o plugin.o plugindata.o postmultiparser.o rebus.o request.o session.o sessioncontainer.o sessionmanager.o sessionparser.o synchro.o system.o textstream.o thumb.o users.o

File diff suppressed because it is too large Load Diff

View File

@@ -18,17 +18,24 @@
#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 "notify.h"
#include "db.h"
#include "db/db.h"
#include "functions/functions.h"
#include "templates/templates.h"
#include "templatesnotify/templatesnotify.h"
#include "compress.h"
#include "htmlfilter.h"
#include "getparser.h"
#include "postparser.h"
#include "cookieparser.h"
#include "postmultiparser.h"
#include "acceptencodingparser.h"
@@ -39,11 +46,19 @@ 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;
@@ -54,12 +69,9 @@ public:
// users sessions
SessionManager session_manager;
// notifications (by emails)
Notify notify;
// database
Db db;
DbConn db_conn;
@@ -71,13 +83,15 @@ public:
System system;
// false at the beginning
// !! moze to do loggera dac?
bool stdout_is_closed;
/*
controller
controllers
(note that the whole app object is actually a controller too)
*/
// functions (ls, cat, emacs, ...)
@@ -89,18 +103,70 @@ public:
*/
Templates templates;
TemplatesNotify templates_notify;
private:
bool CreateFCGISocket();
enum Header
{
h_200,
h_404,
h_403
};
GetParser get_parser;
PostParser post_parser;
PostMultiParser post_multi_parser;
CookieParser cookie_parser;
AcceptEncodingParser accept_encoding_parser;
Compress compress;
HTMLFilter html_filter;
std::wstring clean_html, html_with_debug;
FCGX_Request fcgi_request;
int fcgi_socket;
Synchro synchro;
pthread_t signal_thread;
std::string url_to_fetch_on_exit;
void ProcessRequestThrow();
void ProcessRequest();
bool BaseUrlRedirect();
void DeleteAllPluginsData();
void MakePage();
void Make();
void ReadAdditionalInfo();
void SaveSessionsIfNeeded(); // !! wywalic do managara sesji??
void SaveSessionsIfNeeded(); // !! wywalic do menagera sesji??
void LogAccess();
void ReadRequest();
void SendAnswer();
void SetEnv(const char * & env, const char * name);
void ReadEnvVariables();
void ReadGetPostVars();
void CheckIE();
void CheckKonqueror();
void CheckRequestMethod();
void CheckFCGIRole();
void SetHtmlFilterConf();
void PrepareSessionCookie();
void AddDebugInfo(std::wstring & out);
void FilterCompressSend(bool compressing, const std::wstring & source_ref);
void SendHeaders(bool compressing, Header header);
bool IsCompressionAllowed(const std::wstring & source);
bool CanSendContent(Header header);
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();
// !! dodac do session managera?
time_t last_sessions_save;

229
core/basethread.cpp Executable file
View File

@@ -0,0 +1,229 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#include <errno.h>
#include "basethread.h"
#include "log.h"
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;
}
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;
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;
}

121
core/basethread.h Executable file
View File

@@ -0,0 +1,121 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilecmslucorebasethread
#define headerfilecmslucorebasethread
#include <pthread.h>
#include "synchro.h"
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();
// 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
void WakeUpThread();
// waiting until the thread exits
// you should call WakeUpThread() before
void WaitForThread();
// virtual methods which should/can be inherited by your class
// the methods will be called from the other thread
// 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() {}
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();
};
#endif

View File

@@ -10,6 +10,17 @@
#include "bbcodeparser.h"
bool BBCODEParser::Equal(const wchar_t * str1, const wchar_t * str2)
{
while( *str1 == *str2 && *str1 != 0 )
{
str1 += 1;
str2 += 1;
}
return *str1 == *str2;
}
@@ -58,7 +69,7 @@ bool BBCODEParser::IsClosingXmlSimpleTagMark()
// one enter will generate one <br>
// two enters or more will generate only two br (<br><br>)
void BBCODEParser::PutNormalText(const char * str, const char * end)
void BBCODEParser::PutNormalText(const wchar_t * str, const wchar_t * end)
{
int br_len;
@@ -93,7 +104,7 @@ int br_len;
if( !has_open_ol_tag && !has_open_ul_tag && !has_open_li_tag )
{
for(int i=0 ; i < br_len ; ++i)
(*out_string) += "<br>\n";
(*out_string) += L"<br>\n";
}
}
else
@@ -105,14 +116,14 @@ int br_len;
}
void BBCODEParser::PutNormalTextTrim(const char * str, const char * end)
void BBCODEParser::PutNormalTextTrim(const wchar_t * str, const wchar_t * end)
{
// we don't use trimming in bbcode parser
PutNormalText(str, end);
}
void BBCODEParser::ReadNormalTextSkipWhite(const char * & start, const char * & last_non_white)
void BBCODEParser::ReadNormalTextSkipWhite(const wchar_t * & start, const wchar_t * & last_non_white)
{
}
@@ -123,8 +134,8 @@ void BBCODEParser::CheckExceptions()
{
if( pstack[stack_len-1].type == Item::opening &&
pstack[stack_len-2].type == Item::opening &&
IsNameEqual("*", pstack[stack_len-1].name) &&
IsNameEqual("*", pstack[stack_len-2].name) )
IsNameEqual(L"*", pstack[stack_len-1].name) &&
IsNameEqual(L"*", pstack[stack_len-2].name) )
{
// removing the last [*] from the stack
// </li> was put automatically
@@ -162,20 +173,20 @@ void BBCODEParser::CheckExceptions()
at the beginning and at the end
(because otherwise a space would be changed to %20 and this were probably not what you really wanted)
*/
const BBCODEParser::Tags * BBCODEParser::FindTag(const char * tag)
const BBCODEParser::Tags * BBCODEParser::FindTag(const wchar_t * tag)
{
static Tags tags[] = {
{"*", "li", ">", false},
{"b", "em", ">", true},
{"i", "span", " class=\"bbitalic\">", true},
{"u", "span", " class=\"bbunderline\">", true},
{"s", "span", " class=\"bbstrike\">", true},
{"code", "code", " class=\"bbcode\">", false},
{"list", "ul", " class=\"bblist\">", false},
{"color", "span", " class=\"bbcol%1\">", true},
{"url", "a", " href=\"%u1\">", true},
{"img", "img", " alt=\"%1\" src=\"%u2\">", true},
{"quote", "div", " class=\"bbquote\">\n<span class=\"bbquotewho\">%1</span><br>\n", false},
{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;
@@ -183,7 +194,7 @@ const BBCODEParser::Tags * BBCODEParser::FindTag(const char * tag)
for(i=0 ; i<len ; ++i)
{
if( strcmp(tag, tags[i].bbcode) == 0 )
if( Equal(tag, tags[i].bbcode) )
return &tags[i];
}
@@ -191,7 +202,7 @@ return 0;
}
void BBCODEParser::PrintArgumentCheckQuotes(const char * & start, const char * & end)
void BBCODEParser::PrintArgumentCheckQuotes(const wchar_t * & start, const wchar_t * & end)
{
// skipping white characters from the argument
while( start<end && IsWhite(*start) )
@@ -230,7 +241,7 @@ void BBCODEParser::PrintEncode(int c)
{
if( c == '&' )
{
(*out_string) += "&amp;";
(*out_string) += L"&amp;";
}
else
if( (c>='a' && c<='z') ||
@@ -244,8 +255,8 @@ void BBCODEParser::PrintEncode(int c)
}
else
{
char buffer[20];
sprintf(buffer, "%02X", c);
wchar_t buffer[20];
swprintf(buffer, 20, L"%02X", c);
(*out_string) += '%';
(*out_string) += buffer;
@@ -257,22 +268,22 @@ void BBCODEParser::PrintEscape(int c, bool change_quote)
{
if( c == '<' )
{
(*out_string) += "&lt;";
(*out_string) += L"&lt;";
}
else
if( c == '>' )
{
(*out_string) += "&gt;";
(*out_string) += L"&gt;";
}
else
if( c == '&' )
{
(*out_string) += "&amp;";
(*out_string) += L"&amp;";
}
else
if( c == '\"' && change_quote )
{
(*out_string) += "&quot;";
(*out_string) += L"&quot;";
}
else
{
@@ -281,7 +292,7 @@ void BBCODEParser::PrintEscape(int c, bool change_quote)
}
void BBCODEParser::PrintArgumentEncode(const char * start, const char * end)
void BBCODEParser::PrintArgumentEncode(const wchar_t * start, const wchar_t * end)
{
PrintArgumentCheckQuotes(start, end);
TrimWhiteWithNewLines(start, end);
@@ -291,7 +302,7 @@ void BBCODEParser::PrintArgumentEncode(const char * start, const char * end)
}
void BBCODEParser::PrintArgumentEscape(const char * start, const char * end)
void BBCODEParser::PrintArgumentEscape(const wchar_t * start, const wchar_t * end)
{
PrintArgumentCheckQuotes(start, end);
@@ -300,9 +311,9 @@ void BBCODEParser::PrintArgumentEscape(const char * start, const char * end)
}
void BBCODEParser::CheckOpeningTag(const Tags * tag, const char * tag_name, bool & condition)
void BBCODEParser::CheckOpeningTag(const Tags * tag, const wchar_t * tag_name, bool & condition)
{
if( strcmp(tag->html_tag, tag_name) == 0 )
if( Equal(tag->html_tag, tag_name) )
{
if( condition )
{
@@ -319,13 +330,13 @@ void BBCODEParser::CheckOpeningTag(const Tags * tag)
{
bool has_list_tag = has_open_ul_tag || has_open_ol_tag;
CheckOpeningTag(tag, "li", has_open_li_tag);
CheckOpeningTag(tag, "ul", has_open_ul_tag);
CheckOpeningTag(tag, "ol", has_open_ol_tag);
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) += "<ul>\n";
(*out_string) += L"<ul>\n";
has_open_ul_tag = true;
}
}
@@ -334,7 +345,7 @@ void BBCODEParser::CheckOpeningTag(const Tags * tag)
void BBCODEParser::PrintEscape(const char * start, const char * end, bool change_quote)
void BBCODEParser::PrintEscape(const wchar_t * start, const wchar_t * end, bool change_quote)
{
for( ; start < end ; ++start)
PrintEscape(*start, change_quote);
@@ -342,7 +353,7 @@ void BBCODEParser::PrintEscape(const char * start, const char * end, bool change
void BBCODEParser::PrintEncode(const char * start, const char * end)
void BBCODEParser::PrintEncode(const wchar_t * start, const wchar_t * end)
{
for( ; start < end ; ++start)
PrintEncode(*start);
@@ -350,7 +361,7 @@ void BBCODEParser::PrintEncode(const char * start, const char * end)
void BBCODEParser::PutOpeningTagFromEzc(const char * start, const char * end)
void BBCODEParser::PutOpeningTagFromEzc(const wchar_t * start, const wchar_t * end)
{
// this can be a tag from Ezc templates system
(*out_string) += '[';
@@ -369,7 +380,7 @@ void BBCODEParser::PutOpeningTagFromEzc(const char * start, const char * end)
void BBCODEParser::PutHtmlArgument1(const char * arg_start, const char * arg_end, bool has_u)
void BBCODEParser::PutHtmlArgument1(const wchar_t * arg_start, const wchar_t * arg_end, bool has_u)
{
if( has_u )
PrintArgumentEncode(arg_start, arg_end);
@@ -379,7 +390,7 @@ void BBCODEParser::PutHtmlArgument1(const char * arg_start, const char * arg_end
void BBCODEParser::TrimWhiteWithNewLines(const char * & start, const char * & end)
void BBCODEParser::TrimWhiteWithNewLines(const wchar_t * & start, const wchar_t * & end)
{
while( start < end && (IsWhite(*start) || *start==10) )
++start;
@@ -392,8 +403,8 @@ void BBCODEParser::TrimWhiteWithNewLines(const char * & start, const char * & en
void BBCODEParser::PutHtmlArgument2(const Tags * tag, bool has_u)
{
const char * start = pchar;
const char * end = pchar;
const wchar_t * start = pchar;
const wchar_t * end = pchar;
bool first_tag_removed = false;
while( *pchar != 0 )
@@ -432,9 +443,9 @@ bool first_tag_removed = false;
void BBCODEParser::PutHtmlArgument(const Tags * tag, const char * arg_start, const char * arg_end)
void BBCODEParser::PutHtmlArgument(const Tags * tag, const wchar_t * arg_start, const wchar_t * arg_end)
{
const char * pattern = tag->html_argument;
const wchar_t * pattern = tag->html_argument;
bool has_u;
while( *pattern )
@@ -478,7 +489,7 @@ bool has_u;
}
void BBCODEParser::PutOpeningTagFromBBCode(const Tags * tag, const char * start, const char * end)
void BBCODEParser::PutOpeningTagFromBBCode(const Tags * tag, const wchar_t * start, const wchar_t * end)
{
CheckOpeningTag(tag);
PutOpeningTagMark();
@@ -487,13 +498,13 @@ void BBCODEParser::PutOpeningTagFromBBCode(const Tags * tag, const char * start,
if( !tag->inline_tag )
{
(*out_string) += "\n";
(*out_string) += L"\n";
SkipWhiteLines();
}
}
void BBCODEParser::PutOpeningTag(const char * start, const char * end)
void BBCODEParser::PutOpeningTag(const wchar_t * start, const wchar_t * end)
{
const Tags * tag = FindTag(LastItem().name);
@@ -520,22 +531,22 @@ void BBCODEParser::PutClosingTag(const Tags * tag)
if( !tag->inline_tag )
{
(*out_string) += "\n";
(*out_string) += L"\n";
SkipWhiteLines();
}
if( strcmp(tag->html_tag, "li") == 0 )
if( Equal(tag->html_tag, L"li") )
has_open_li_tag = false;
if( strcmp(tag->html_tag, "ol") == 0 )
if( Equal(tag->html_tag, L"ol") )
has_open_ol_tag = false;
if( strcmp(tag->html_tag, "ul") == 0 )
if( Equal(tag->html_tag, L"ul") )
has_open_ul_tag = false;
}
void BBCODEParser::PutClosingTag(const char * tag_name)
void BBCODEParser::PutClosingTag(const wchar_t * tag_name)
{
const Tags * tag = FindTag(tag_name);
PutClosingTag(tag);
@@ -556,11 +567,11 @@ void BBCODEParser::Init()
void BBCODEParser::Deinit()
{
if( has_open_li_tag )
(*out_string) += "</li>\n";
(*out_string) += L"</li>\n";
if( has_open_ol_tag )
(*out_string) += "</ol>\n";
(*out_string) += L"</ol>\n";
if( has_open_ul_tag )
(*out_string) += "</ul>\n";
(*out_string) += L"</ul>\n";
}

View File

@@ -22,20 +22,22 @@ class BBCODEParser : public HTMLFilter
struct Tags
{
/*
const char * bbcode;
const char * html_tag;
const char * html_arg_prefix;
const char * html_arg_postfix;
const char * additional_html_tag_prefix;
const char * additional_html_tag_postfix;
const wchar_t * bbcode;
const wchar_t * html_tag;
const wchar_t * html_arg_prefix;
const wchar_t * html_arg_postfix;
const wchar_t * additional_html_tag_prefix;
const wchar_t * additional_html_tag_postfix;
bool inline_tag;
*/
const char * bbcode;
const char * html_tag;
const char * html_argument; // with closing '>'
const wchar_t * bbcode;
const wchar_t * html_tag;
const wchar_t * html_argument; // with closing '>'
bool inline_tag;
};
bool Equal(const wchar_t * str1, const wchar_t * str2);
virtual bool IsValidCharForName(int c);
virtual bool IsOpeningTagMark();
@@ -45,32 +47,32 @@ class BBCODEParser : public HTMLFilter
virtual bool IsClosingXmlSimpleTagMark();
void PutHtmlArgument1(const char * arg_start, const char * arg_end, bool has_u);
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 char * arg_start, const char * arg_end);
void PutHtmlArgument(const Tags * tag, const wchar_t * arg_start, const wchar_t * arg_end);
void PutOpeningTagFromEzc(const char * start, const char * end);
void PutOpeningTagFromBBCode(const Tags * tag, const char * start, const char * end);
void PutOpeningTagFromEzc(const wchar_t * start, const wchar_t * end);
void PutOpeningTagFromBBCode(const Tags * tag, const wchar_t * start, const wchar_t * end);
virtual void PutOpeningTag(const char * start, const char * end);
virtual void PutClosingTag(const char * tag);
virtual void PutOpeningTag(const wchar_t * start, const wchar_t * end);
virtual void PutClosingTag(const wchar_t * tag);
const Tags * FindTag(const char * tag);
void PrintArgumentCheckQuotes(const char * & start, const char * & end);
const Tags * FindTag(const wchar_t * 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 char * start, const char * end, bool change_quote = false);
void PrintEncode(const char * start, const char * end);
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 char * start, const char * end);
void PrintArgumentEscape(const char * start, const char * end);
void PrintArgumentEncode(const wchar_t * start, const wchar_t * end);
void PrintArgumentEscape(const wchar_t * start, const wchar_t * end);
virtual void ReadNormalTextSkipWhite(const char * & start, const char * & last_non_white);
virtual void PutNormalText(const char * str, const char * end);
virtual void PutNormalTextTrim(const char * str, const char * end);
virtual void ReadNormalTextSkipWhite(const wchar_t * & start, const wchar_t * & last_non_white);
virtual void PutNormalText(const wchar_t * str, const wchar_t * end);
virtual void PutNormalTextTrim(const wchar_t * str, const wchar_t * end);
virtual void CheckExceptions();
@@ -80,10 +82,10 @@ class BBCODEParser : public HTMLFilter
void PutClosingTag(const Tags * tag);
void CheckOpeningTag(const Tags * tag, const char * tag_name, bool & condition);
void CheckOpeningTag(const Tags * tag, const wchar_t * tag_name, bool & condition);
void CheckOpeningTag(const Tags * tag);
void TrimWhiteWithNewLines(const char * & start, const char * & end);
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

View File

@@ -68,6 +68,7 @@ bool Config::ReadConfig(bool errors_to_stdout_, bool stdout_is_closed)
log << log2 << "Config: reading a config file" << logend;
parser.SplitSingle(true);
parser.UTF8(true); // config is always read in UTF-8
ConfParser::Status status = parser.Parse( config_file );
@@ -89,183 +90,255 @@ bool Config::ReadConfig(bool errors_to_stdout_, bool stdout_is_closed)
void Config::AssignValues(bool stdout_is_closed)
{
log_file = Text("log_file");
log_notify_file = Text("log_notify_file");
fcgi_socket = Text("fcgi_socket");
fcgi_socket_chmod = Int("fcgi_socket_chmod", 0770);
fcgi_socket_user = Text("fcgi_socket_user");
fcgi_socket_group = Text("fcgi_socket_group");
log_level = Int("log_level", 1);
log_request = Int("log_request", 1);
log_stdout = Bool("log_stdout", false);
demonize = Bool(L"demonize", true);
user = AText(L"user");
group = AText(L"group");
additional_groups = Bool(L"additional_groups", true);
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_stdout = Bool(L"log_stdout", false);
log_db_query = Bool(L"log_db_query", false);
log_plugin_call = Bool(L"log_plugin_call", false);
post_file_max = Int("post_file_max", 8388608); // 8 MB
auth_simplefs_dir = Text("auth_simplefs_dir");
auth_hashfs_dir = Text("auth_hashfs_dir");
auth_tmp_dir = Text("auth_tmp_dir");
post_file_max = Size(L"post_file_max", 8388608); // 8 MB
upload_dir = Text(L"upload_dir");
upload_dirs_chmod = Int(L"upload_dirs_chmod", 0750);
upload_files_chmod = Int(L"upload_files_chmod", 0640);
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);
convert_cmd = Text(L"convert_cmd", L"/usr/local/bin/convert");
templates_dir = Text("templates_dir");
templates_dir_default = Text("templates_dir_default");
http_session_id_name = Text("http_session_id_name");
db_database = Text("db_database");
db_user = Text("db_user");
db_pass = Text("db_pass");
item_url_empty = Text("item_url_empty");
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);
base_server = Text("base_server");
base_url = Text("base_url");
base_url_auth = Text("base_url_auth");
base_url_static = Text("base_url_static");
base_url_common = Text("base_url_common");
http_session_id_name = AText(L"http_session_id_name");
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");
base_server = Text(L"base_server");
base_url = Text(L"base_url");
base_url_static = Text(L"base_url_static");
base_url_common = Text(L"base_url_common");
NoLastSlash(base_server);
NoLastSlash(base_url);
NoLastSlash(base_url_auth);
NoLastSlash(base_url_static);
NoLastSlash(base_url_common);
priv_no_user = Text("priv_no_user", "-- no user --");
priv_no_group = Text("priv_no_group", "-- no group --");
priv_no_user = Text(L"priv_no_user", L"-- no user --");
priv_no_group = Text(L"priv_no_group", L"-- no group --");
session_max_idle = Int("session_max_idle", 10800); // 3h
session_remember_max_idle = Int("session_remember_max_idle", 16070400); // 3 months
session_file = Text("session_file");
session_max_idle = Int(L"session_max_idle", 10800); // 3h
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("compression", true);
html_filter = Bool("html_filter", true);
compression = Bool(L"compression", true);
compression_page_min_size = Int(L"compression_page_min_size", 512);
locale_str = Text("locale", "en");
locale_dir = Text("locale_dir");
locale_dir_default = Text("locale_dir_default");
html_filter = Bool(L"html_filter", true);
html_filter_trim_white = Bool(L"html_filter_trim_white", true);
html_filter_break_lines = Int(L"html_filter_break_lines", 60);
html_filter_tabs = Size(L"html_filter_tabs", 2);
html_filter_orphans = Bool(L"html_filter_orphans", false);
html_filter_orphans_lang_str = AText(L"html_filter_orphans_lang", L"pl");
html_filter_orphans_mode_str = AText(L"html_filter_orphans_mode_str", L"nbsp");
title_separator = Text("title_separator", " / ");
locale_str = Text(L"locale", L"en");
locale_dir = Text(L"locale_dir");
locale_dir_default = Text(L"locale_dir_default");
parser.ListText("plugins", plugin_file);
title_separator = Text(L"title_separator", L" / ");
http_header_send_file = Text(L"http_header_send_file", L"X-LIGHTTPD-send-file");
password_min_size = Size(L"password_min_size", 5);
debug_info = Bool(L"debug_info", false);
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);
parser.ListText(L"plugins", plugin_file);
time_zone_offset = Int(L"time_zone_offset", 0);
time_zone_offset_guest = Int(L"time_zone_offset_guest", 0);
utf8 = Bool(L"utf8", true);
symlinks_follow_max = Size(L"symlinks_follow_max", 20);
ticket_form_prefix = Text(L"ticket_form_prefix", L"ticketparam");
}
void Config::SetAdditionalVariables()
{
SetHttpHost(base_url, base_url_http_host);
SetHttpHost(base_url_auth, base_url_auth_http_host);
if( html_filter_orphans_lang_str == "pl" )
html_filter_orphans_lang = HTMLFilter::lang_pl;
else
if( html_filter_orphans_lang_str == "cz" )
html_filter_orphans_lang = HTMLFilter::lang_cz;
else
if( html_filter_orphans_lang_str == "sk" )
html_filter_orphans_lang = HTMLFilter::lang_sk;
else
html_filter_orphans_lang = HTMLFilter::lang_none;
if( html_filter_orphans_mode_str == "160" )
html_filter_orphans_mode = HTMLFilter::orphan_160space;
else
html_filter_orphans_mode = HTMLFilter::orphan_nbsp;
}
void Config::SetHttpHost(const std::string & in, std::string & out)
void Config::SetHttpHost(const std::wstring & in, std::wstring & out)
{
if( strncmp(in.c_str(), "http://", 7) == 0 )
out = in.substr(7);
const char http[] = "http://";
const char https[] = "https://";
size_t http_len = sizeof(http) / sizeof(char) - 1;
size_t https_len = sizeof(https) / sizeof(char) - 1;
if( IsSubString(http, in.c_str()) )
out = in.substr(http_len);
else
if( strncmp(in.c_str(), "https://", 8) == 0 )
out = in.substr(8);
if( IsSubString(https, in.c_str()) )
out = in.substr(https_len);
else
out.clear(); // if empty the RequestController::BaseUrlRedirect() returns false and no redirecting will be done
}
std::string Config::Text(const char * name)
std::wstring Config::Text(const wchar_t * name)
{
return parser.Text(name);
}
std::string Config::Text(const char * name, const char * def)
std::wstring Config::Text(const wchar_t * name, const wchar_t * def)
{
return parser.Text(name, def);
}
std::string Config::Text(const std::string & name, const std::string & def)
std::wstring Config::Text(const std::wstring & name, const std::wstring & def)
{
return parser.Text(name, def);
}
int Config::Int(const char * name)
std::string Config::AText(const wchar_t * name)
{
return parser.AText(name);
}
std::string Config::AText(const wchar_t * name, const wchar_t * def)
{
return parser.AText(name, def);
}
std::string Config::AText(const std::wstring & name, const std::wstring & def)
{
return parser.AText(name, def);
}
int Config::Int(const wchar_t * name)
{
return parser.Int(name);
}
int Config::Int(const char * name, int def)
int Config::Int(const wchar_t * name, int def)
{
return parser.Int(name, def);
}
int Config::Int(const std::string & name, int def)
int Config::Int(const std::wstring & name, int def)
{
return parser.Int(name, def);
}
bool Config::Bool(const char * name)
size_t Config::Size(const wchar_t * name)
{
return parser.Size(name);
}
size_t Config::Size(const wchar_t * name, size_t def)
{
return parser.Size(name, def);
}
size_t Config::Size(const std::wstring & name, size_t def)
{
return parser.Size(name, def);
}
bool Config::Bool(const wchar_t * name)
{
return parser.Bool(name);
}
bool Config::Bool(const char * name, bool def)
bool Config::Bool(const wchar_t * name, bool def)
{
return parser.Bool(name, def);
}
bool Config::Bool(const std::string & name, bool def)
bool Config::Bool(const std::wstring & name, bool def)
{
return parser.Bool(name, def);
}
void Config::ListText(const char * name, std::vector<std::string> & list)
void Config::ListText(const wchar_t * name, std::vector<std::wstring> & list)
{
parser.ListText(name, list);
}
void Config::ListText(const std::string & name, std::vector<std::string> & list)
void Config::ListText(const std::wstring & name, std::vector<std::wstring> & list)
{
parser.ListText(name, list);
}
void Config::NoLastSlash(std::string & s)
void Config::Print(std::ostream & out)
{
if( s.empty() )
return;
size_t i = s.size();
for( ; i>0 && s[i-1]=='/' ; --i);
if( i < s.size() )
s.erase(i);
}
void Config::NoFirstHttp(std::string & s)
{
if( s.empty() )
return;
const char http[] = "http://";
const char https[] = "https://";
if( IsSubStringNoCase(http, s.c_str()) )
{
s.erase(0, sizeof(http)/sizeof(char));
}
else
if( IsSubStringNoCase(https, s.c_str()) )
{
s.erase(0, sizeof(https)/sizeof(char));
}
parser.Print(out);
}
@@ -274,4 +347,3 @@ void Config::NoFirstHttp(std::string & s)

View File

@@ -12,6 +12,7 @@
#include <string>
#include "confparser.h"
#include "htmlfilter.h"
@@ -20,9 +21,28 @@ class Config
{
public:
// name of the config file (full path can be)
// 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 name (to which drop privileges)
// used only if winix is started as the root
std::string user;
// system group 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;
@@ -32,12 +52,29 @@ public:
int log_level;
// logging to stdout too
// only if demonize is 'false'
// default: false
bool log_stdout;
// how many requests should be logged in the same time
// how many requests should be saved in the same time
// default: 1
int log_request;
// whether to save each line of the config (use it for debug purposes)
// default: false
bool log_save_each_line;
// logging db queries
// default: false
bool log_db_query;
// logging when a plugin function is called
// default: false
bool log_plugin_call;
// request delimiter in the log file, default "---------"
std::wstring log_delimiter;
// fast cgi: socket (unix domain)
std::string fcgi_socket;
@@ -50,8 +87,26 @@ public:
// fast cgi: group of the socket
std::string fcgi_socket_group;
std::string templates_dir;
std::string templates_dir_default; // templates from winix
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' function
// default: false
bool template_only_root_use_template_fun;
std::string db_database;
std::string db_user;
@@ -65,8 +120,8 @@ public:
bool base_url_redirect;
// string used in a place where is a user (or group) selected
std::string priv_no_user;
std::string priv_no_group;
std::wstring priv_no_user;
std::wstring priv_no_group;
// time in seconds when the user will be automatically logged out (iddle time)
int session_max_idle;
@@ -78,87 +133,209 @@ public:
// this file is used when the program is starting and ending
std::string session_file;
// how many sessions can be (zero turn off this checking)
// default: 1000000 (one milion)
size_t session_max;
// allow the html ouput to be compressed
bool compression;
// plugins
std::vector<std::string> plugin_file;
// the html code is cleaned by our filter
// if the output is shorter than this value then it will not be compressed
int compression_page_min_size;
// 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 lines (lines without a white character) should be break (inserted a space)
// default: after 60 non white characters will be put a space
// set zero to turn off
int html_filter_break_lines;
// 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: false
bool html_filter_orphans;
// language for html orphans
// default: pl
// can be either: "pl" or "cz" or "sk"
std::string html_filter_orphans_lang_str;
HTMLFilter::Lang html_filter_orphans_lang;
// orphans mode
// either: "nbsp" or "160"
// default: "nbsp"
std::string html_filter_orphans_mode_str;
HTMLFilter::OrphanMode html_filter_orphans_mode;
// the url of a new empty item (if there is not the subject too)
std::string item_url_empty;
std::wstring item_url_empty;
// maximum length of a file send by post multipart form
// 0 - not used
int post_file_max;
size_t post_file_max;
// directories for static files
std::string auth_simplefs_dir;
std::string auth_hashfs_dir;
// directory for static files
std::wstring upload_dir;
// temporary directory for static content used by the upload function
// should be on the same partition as auth_simplefs_dir and auth_hashfs_dir
std::string auth_tmp_dir;
// chmod of newly created directories (under upload_dir)
// default: 0750
int upload_dirs_chmod;
// default locale: en pl
std::string locale_str;
// 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;
// the convert program
// default: /usr/local/bin/convert
std::wstring convert_cmd;
// locale: en, pl
// default: en
std::wstring locale_str;
// directory with locale files
std::string locale_dir;
std::wstring locale_dir;
// directory with default locale files (those from winix)
std::string locale_dir_default;
std::wstring locale_dir_default;
// the main address of the server (e.g. someserver.com) (without the 'www' part etc)
std::string base_server;
std::wstring base_server;
// the main address of the site (e.g. http://www.someserver.com)
std::string base_url;
// static content authorized by winix
std::string base_url_auth;
std::wstring base_url;
// static content not authorized by winix
std::string base_url_static;
std::wstring base_url_static;
// additional static server for common content (not authorized)
std::string base_url_common;
std::wstring base_url_common;
// separator used in <title> html tag
std::string title_separator;
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;
// the minimum size of a password for new users (function: adduser)
// default: 5
size_t password_min_size;
// prints additional information (in the end of the html page as a commentary)
bool debug_info;
// 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;
// temporarily we do not support time zones per user
// there is one offset for all users
// default: 0
int time_zone_offset;
// time zone offset for guests (not logged users)
// default: 0
int time_zone_offset_guest;
// 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;
/*
*/
// based on base_url
// set by SetAdditionalVariables()
// without the first part http:// (or https://) or the whole string is empty
std::string base_url_http_host;
std::string base_url_auth_http_host;
std::wstring base_url_http_host;
Config();
bool ReadConfig(bool errors_to_stdout_, bool stdout_is_closed = true);
std::string Text(const char * name);
std::string Text(const char * name, const char * def);
std::string Text(const std::string & name, const std::string & def);
int Int(const char *);
int Int(const char * name, int def);
int Int(const std::string & name, int def);
bool Bool(const char *);
bool Bool(const char * name, bool def);
bool Bool(const std::string & name, bool def);
void ListText(const char * name, std::vector<std::string> & list);
void ListText(const std::string & name, std::vector<std::string> & list);
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 std::wstring & def);
std::string AText(const wchar_t * name);
std::string AText(const wchar_t * name, const wchar_t * def);
std::string AText(const std::wstring & name, const std::wstring & def);
void NoLastSlash(std::string & s);
void NoFirstHttp(std::string & s);
int Int(const wchar_t *);
int Int(const wchar_t * name, int def);
int Int(const std::wstring & name, int 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);
void ListText(const wchar_t * name, std::vector<std::wstring> & list);
void ListText(const std::wstring & name, std::vector<std::wstring> & list);
// for debug
void Print(std::ostream & out);
private:
void ShowError();
void AssignValues(bool stdout_is_closed);
void SetHttpHost(const std::string & in, std::string & out);
void SetHttpHost(const std::wstring & in, std::wstring & out);
void SetAdditionalVariables();
ConfParser parser;

View File

@@ -7,8 +7,11 @@
*
*/
#include <cstdlib>
#include <wchar.h>
#include "confparser.h"
#include "misc.h"
#include "utf8.h"
@@ -24,9 +27,12 @@ ConfParser::ConfParser()
list_delimiter = ',';
split_single = false;
skip_empty = false;
use_escape_char = true;
input_as_utf8 = false;
default_str = "";
default_str = L"";
default_int = 0;
default_size = 0;
default_bool = false;
}
@@ -43,6 +49,15 @@ void ConfParser::SkipEmpty(bool skip)
}
void ConfParser::UseEscapeChar(bool escape)
{
use_escape_char = escape;
}
ConfParser::Status ConfParser::Parse(const char * file_name)
{
line = 1;
@@ -74,6 +89,23 @@ ConfParser::Status ConfParser::Parse(const std::string & file_name)
ConfParser::Status ConfParser::Parse(const wchar_t * file_name)
{
Ezc::WideToUTF8(file_name, afile_name);
return Parse(afile_name.c_str());
}
ConfParser::Status ConfParser::Parse(const std::wstring & file_name)
{
return Parse(file_name.c_str());
}
ConfParser::Status ConfParser::ParseFile()
{
ReadChar();
@@ -140,7 +172,7 @@ void ConfParser::AddOption()
void ConfParser::DeleteFromTable(const std::string & var)
void ConfParser::DeleteFromTable(const std::wstring & var)
{
Table::iterator i = table.find(var);
@@ -150,7 +182,7 @@ void ConfParser::DeleteFromTable(const std::string & var)
void ConfParser::DeleteFromTableSingle(const std::string & var)
void ConfParser::DeleteFromTableSingle(const std::wstring & var)
{
TableSingle::iterator i = table_single.find(var);
@@ -251,7 +283,7 @@ bool ConfParser::ReadValueQuoted()
while( lastc != '"' && lastc != -1 )
{
if( lastc == '\\' )
if( use_escape_char && lastc == '\\' )
ReadChar();
value_item += lastc;
@@ -294,7 +326,33 @@ return true;
}
int ConfParser::ReadChar()
int ConfParser::ReadUTF8Char()
{
int c;
bool correct;
lastc = -1;
do
{
Ezc::UTF8ToInt(file, c, correct);
if( !file )
return lastc;
}
while( !correct );
lastc = c;
if( lastc == '\n' )
++line;
return lastc;
}
int ConfParser::ReadASCIIChar()
{
lastc = file.get();
@@ -305,6 +363,15 @@ return lastc;
}
int ConfParser::ReadChar()
{
if( input_as_utf8 )
return ReadUTF8Char();
return ReadASCIIChar();
}
bool ConfParser::IsWhite(int c)
{
// dont use '\n' here
@@ -350,9 +417,9 @@ void ConfParser::SkipLine()
void ConfParser::Trim(std::string & s)
void ConfParser::Trim(std::wstring & s)
{
std::string::size_type i;
std::wstring::size_type i;
if( s.empty() )
return;
@@ -369,7 +436,7 @@ std::string::size_type i;
// deleting white characters at the end
if( i != s.size() - 1 )
s.erase(i+1, std::string::npos);
s.erase(i+1, std::wstring::npos);
// looking for white characters at the beginning
for(i=0 ; i<s.size() && IsWhite(s[i]) ; ++i);
@@ -384,20 +451,20 @@ std::string::size_type i;
std::string ConfParser::Text(const char * name)
std::wstring ConfParser::Text(const wchar_t * name)
{
return Text(std::string(name), default_str);
return Text(std::wstring(name), default_str);
}
std::string ConfParser::Text(const char * name, const char * def)
std::wstring ConfParser::Text(const wchar_t * name, const wchar_t * def)
{
return Text(std::string(name), std::string(def));
return Text(std::wstring(name), std::wstring(def));
}
std::string ConfParser::Text(const std::string & name, const std::string & def)
std::wstring ConfParser::Text(const std::wstring & name, const std::wstring & def)
{
TableSingle::iterator i = table_single.find(name);
@@ -416,27 +483,63 @@ return i->second;
int ConfParser::Int(const char * name)
std::string ConfParser::AText(const wchar_t * name)
{
return Int(std::string(name), default_int);
std::wstring res = Text(name);
std::string ares;
Ezc::WideToUTF8(res, ares);
return ares;
}
int ConfParser::Int(const char * name, int def)
std::string ConfParser::AText(const wchar_t * name, const wchar_t * def)
{
return Int(std::string(name), def);
std::wstring res = Text(name, def);
std::string ares;
Ezc::WideToUTF8(res, ares);
return ares;
}
int ConfParser::ToInt(const std::string & value)
std::string ConfParser::AText(const std::wstring & name, const std::wstring & def)
{
long res = (value[0] == '0')? strtol(value.c_str() + 1, 0, 8) : strtol(value.c_str(), 0, 10);
std::wstring res = Text(name, def);
std::string ares;
Ezc::WideToUTF8(res, ares);
return ares;
}
int ConfParser::Int(const wchar_t * name)
{
return Int(std::wstring(name), default_int);
}
int ConfParser::Int(const wchar_t * name, int def)
{
return Int(std::wstring(name), def);
}
int ConfParser::ToInt(const std::wstring & value)
{
long res = (value[0] == '0')? wcstol(value.c_str() + 1, 0, 8) : wcstol(value.c_str(), 0, 10);
return res;
return static_cast<int>(res);
}
int ConfParser::Int(const std::string & name, int def)
int ConfParser::Int(const std::wstring & name, int def)
{
TableSingle::iterator i = table_single.find(name);
@@ -454,28 +557,70 @@ return ToInt(i->second);
}
bool ConfParser::Bool(const char * name)
size_t ConfParser::Size(const wchar_t * name)
{
return Bool(std::string(name), default_bool);
return Size(std::wstring(name), default_size);
}
bool ConfParser::Bool(const char * name, bool def)
size_t ConfParser::Size(const wchar_t * name, size_t def)
{
return Bool(std::string(name), def);
return Size(std::wstring(name), def);
}
bool ConfParser::ToBool(const std::string & value)
size_t ConfParser::ToSize(const std::wstring & value)
{
return ( EqualNoCase(value.c_str(), "true") ||
EqualNoCase(value.c_str(), "yes") ||
EqualNoCase(value.c_str(), "1")
unsigned long res = (value[0] == '0')? wcstoul(value.c_str() + 1, 0, 8) : wcstoul(value.c_str(), 0, 10);
return static_cast<size_t>(res);
}
size_t ConfParser::Size(const std::wstring & name, size_t def)
{
TableSingle::iterator i = table_single.find(name);
if( i == table_single.end() )
{
Table::iterator t = table.find(name);
if( t == table.end() || t->second.empty() )
return def;
return ToSize(t->second[0]);
}
return ToSize(i->second);
}
bool ConfParser::Bool(const wchar_t * name)
{
return Bool(std::wstring(name), default_bool);
}
bool ConfParser::Bool(const wchar_t * name, bool def)
{
return Bool(std::wstring(name), def);
}
bool ConfParser::ToBool(const std::wstring & value)
{
return ( EqualNoCase(value.c_str(), L"true") ||
EqualNoCase(value.c_str(), L"yes") ||
EqualNoCase(value.c_str(), L"1")
);
}
bool ConfParser::Bool(const std::string & name, bool def)
bool ConfParser::Bool(const std::wstring & name, bool def)
{
TableSingle::iterator i = table_single.find(name);
@@ -493,7 +638,7 @@ return ToBool(i->second);
}
void ConfParser::SetDefaultText(const std::string & def)
void ConfParser::SetDefaultText(const std::wstring & def)
{
default_str = def;
}
@@ -503,6 +648,11 @@ void ConfParser::SetDefaultInt(int def)
default_int = def;
}
void ConfParser::SetDefaultSize(size_t def)
{
default_size = def;
}
void ConfParser::SetDefaultBool(bool def)
{
default_bool = def;
@@ -512,13 +662,13 @@ void ConfParser::SetDefaultBool(bool def)
// in lists we don't use default values
void ConfParser::ListText(const char * name, std::vector<std::string> & list)
void ConfParser::ListText(const wchar_t * name, std::vector<std::wstring> & list)
{
ListText(std::string(name), list);
ListText(std::wstring(name), list);
}
void ConfParser::ListText(const std::string & name, std::vector<std::string> & list)
void ConfParser::ListText(const std::wstring & name, std::vector<std::wstring> & list)
{
list.clear();
@@ -539,3 +689,41 @@ void ConfParser::ListText(const std::string & name, std::vector<std::string> & l
}
}
void ConfParser::UTF8(bool utf)
{
input_as_utf8 = utf;
}
void ConfParser::Print(std::ostream & out)
{
TableSingle::iterator i1;
for(i1 = table_single.begin() ; i1 != table_single.end() ; ++i1)
{
Ezc::WideToUTF8(i1->first, out);
out << '=';
Ezc::WideToUTF8(i1->second, out);
out << std::endl;
}
Table::iterator i2;
Value::iterator i3;
for(i2 = table.begin() ; i2 != table.end() ; ++i2)
{
Ezc::WideToUTF8(i2->first, out);
out << '=';
for(i3 = i2->second.begin() ; i3 != i2->second.end() ; ++i3)
{
Ezc::WideToUTF8(*i3, out);
out << ',';
}
out << std::endl;
}
}

View File

@@ -122,6 +122,7 @@ config syntax:
"\a" gives "a"
"\\" gives "\"
"\Z" gives "Z" and so on
you can call UseEscapeChar(false) to turn this off
*/
@@ -150,6 +151,8 @@ public:
*/
Status Parse(const char * file_name);
Status Parse(const std::string & file_name);
Status Parse(const wchar_t * file_name);
Status Parse(const std::wstring & file_name);
/*
@@ -162,8 +165,8 @@ public:
this is the table which represents your config file
in the Table map: the first (key) is your 'option' and the second is 'list'
*/
typedef std::vector<std::string> Value;
typedef std::map<std::string, Value> Table;
typedef std::vector<std::wstring> Value;
typedef std::map<std::wstring, Value> Table;
Table table;
@@ -173,10 +176,10 @@ public:
option2 = value2
then you can call SplitSingle(true) for not inserting single values to
previous 'table' but instead to 'table_single'
table_single as the second parameter takes only std::string (instead of the whole std::vector)
table_single as the second parameter takes only std::wstring (instead of the whole std::vector)
so you can save a little memory from not using std::vector
*/
typedef std::map<std::string, std::string> TableSingle;
typedef std::map<std::wstring, std::wstring> TableSingle;
TableSingle table_single;
@@ -202,6 +205,15 @@ public:
void SkipEmpty(bool skip);
/*
'\' character is used to escape other characters in a quoted string
so "some \t t\"ext" will produce "some t t"ext"
(this is only use in quoted string)
default: true
*/
void UseEscapeChar(bool escape);
/*
those methods are used to extract information from table or table_single
as a parameter they take the name of an option
@@ -209,15 +221,21 @@ public:
they return appropriate value (either text, int or boolean)
(in lists they return the first item if exists)
*/
std::string Text(const char * name);
std::string Text(const char * name, const char * def);
std::string Text(const std::string & name, const std::string & def);
int Int(const char *);
int Int(const char * name, int def);
int Int(const std::string & name, int def);
bool Bool(const char *);
bool Bool(const char * name, bool def);
bool Bool(const std::string & name, bool def);
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 std::wstring & def);
std::string AText(const wchar_t * name);
std::string AText(const wchar_t * name, const wchar_t * def);
std::string AText(const std::wstring & name, const std::wstring & def);
int Int(const wchar_t *);
int Int(const wchar_t * name, int def);
int Int(const std::wstring & name, int 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);
/*
@@ -226,11 +244,12 @@ public:
if you don't set it directly then:
default text is: "" (empty)
default int is: 0
default int or size is: 0
default bool is: false
*/
void SetDefaultText(const std::string & def);
void SetDefaultText(const std::wstring & def);
void SetDefaultInt(int def);
void SetDefaultSize(size_t def);
void SetDefaultBool(bool def);
@@ -238,8 +257,21 @@ public:
those methods are used to extract lists
note: if there is one option in table_single they will return it
*/
void ListText(const char * name, std::vector<std::string> & list);
void ListText(const std::string & name, std::vector<std::string> & list);
void ListText(const wchar_t * name, std::vector<std::wstring> & list);
void ListText(const std::wstring & name, std::vector<std::wstring> & list);
/*
if true then the input file is treated as UTF-8
*/
void UTF8(bool utf);
/*
printing the content
(for debug purposes)
*/
void Print(std::ostream & out);
private:
@@ -247,13 +279,13 @@ private:
/*
last read variable (option)
*/
std::string variable;
std::wstring variable;
/*
last read list item
*/
std::string value_item;
std::wstring value_item;
/*
@@ -294,6 +326,7 @@ private:
/*
last read char
or -1 if the end
*/
int lastc;
@@ -321,19 +354,34 @@ private:
bool skip_empty;
/*
input file is in UTF-8
default: false
*/
bool input_as_utf8;
std::string default_str;
/*
if true you can use an escape character '\' in quoted values
*/
bool use_escape_char;
std::string afile_name;
std::wstring default_str;
int default_int;
size_t default_size;
bool default_bool;
int ToInt(const std::string & value);
bool ToBool(const std::string & value);
int ToInt(const std::wstring & value);
size_t ToSize(const std::wstring & value);
bool ToBool(const std::wstring & value);
Status ParseFile();
void AddOption();
void DeleteFromTable(const std::string & var);
void DeleteFromTableSingle(const std::string & var);
void DeleteFromTable(const std::wstring & var);
void DeleteFromTableSingle(const std::wstring & var);
bool ReadVariable();
bool ReadValue();
@@ -342,13 +390,15 @@ private:
bool ReadValueQuoted();
bool ReadValueSimple(bool use_list_delimiter = false);
int ReadUTF8Char();
int ReadASCIIChar();
int ReadChar();
bool IsWhite(int c);
bool IsVariableChar(int c);
void SkipWhite();
void SkipWhiteLines();
void SkipLine();
void Trim(std::string & s);
void Trim(std::wstring & s);
};

View File

@@ -21,7 +21,7 @@ class CookieParser : public HttpSimpleParser
{
const char * cookie_string;
CookieTable & cookie_table;
CookieTab * cookie_tab;
protected:
@@ -41,7 +41,7 @@ protected:
// Cookie names are case insensitive according to section 3.1 of RFC 2965
ToLower(name);
std::pair<CookieTable::iterator, bool> res = cookie_table.insert( std::make_pair(name, value) );
std::pair<CookieTab::iterator, bool> res = cookie_tab->insert( std::make_pair(name, value) );
log << log2 << "Cookie, name: \"" << name << "\", value: \"" << value << "\"";
@@ -58,7 +58,7 @@ protected:
public:
CookieParser(const char * cookie_string_, CookieTable & cookie_table_) : cookie_string(cookie_string_), cookie_table(cookie_table_)
CookieParser()
{
HttpSimpleParser::separator = ';';
HttpSimpleParser::value_can_be_quoted = true;
@@ -66,6 +66,16 @@ public:
HttpSimpleParser::recognize_special_chars = false;
}
// cookie_string can be null
void Parse(const char * cookie_string_, CookieTab & cookie_tab_)
{
cookie_string = cookie_string_;
cookie_tab = &cookie_tab_;
HttpSimpleParser::Parse();
}
};

File diff suppressed because it is too large Load Diff

256
core/db.h
View File

@@ -1,256 +0,0 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilecmslucoredb
#define headerfilecmslucoredb
#include <string>
#include <vector>
#include <map>
#include <sstream>
#include <libpq-fe.h>
#include <cstdio>
#include <ctime>
#include <cstring>
#include "item.h"
#include "user.h"
#include "group.h"
#include "thread.h"
#include "error.h"
#include "dircontainer.h"
#include "ugcontainer.h"
#include "ticket.h"
class Db
{
public:
Db(bool close_at_end_ = true);
~Db();
// !! przerobic tak aby GetItem zwracalo wszystkie pozycja
// !! GetFile tylko dla plikow
// !! GetDir tylko dla katalogow
// !! GetFile i GetDir beda uzywac GetItem
void Init(const std::string & database, const std::string & user, const std::string & pass);
bool CheckUser(std::string & login, std::string & password, long & user_id);
Error AddUser(User & user, const std::string & password);
Error AddItem(Item & item);
Error EditItemById(Item & item, bool with_url = true);
Error EditItemByUrl(Item & item, bool with_url = true);
void CheckAllUrlSubject();
struct ItemQuery
{
// id is selected always
bool sel_parent_id; // parent_id
bool sel_user_id; // user_id, modification_user_id
bool sel_group_id; // group_id
bool sel_guest_name; // guest_name
bool sel_privileges; // privileges
bool sel_date; // date_creation, date_modification
bool sel_subject; // subject
bool sel_content; // content, content_type, (content_id)
bool sel_url; // url
bool sel_type; // type (dir, file, none)
bool sel_default_item; // default_item
bool sel_auth; // auth, auth_path
bool where_id; //
bool where_parent_id; //
bool where_type;
bool where_auth;
long id; // if where_id is true
long parent_id; // if where_parent_id is true
Item::Type type;
Item::Auth auth;
bool auth_equal; // if true means auth should be equal
bool sort_asc;
void SetAllSel(bool sel)
{
sel_parent_id = sel;
sel_user_id = sel;
sel_group_id = sel;
sel_guest_name = sel;
sel_privileges = sel;
sel_date = sel;
sel_subject = sel;
sel_content = sel;
sel_url = sel;
sel_type = sel;
sel_default_item= sel;
sel_auth = sel;
}
void SetAllWhere(bool where_)
{
where_id = where_;
where_parent_id = where_;
where_type = where_;
where_auth = where_;
}
void SetAll(bool sel, bool where_)
{
SetAllSel(sel);
SetAllWhere(where_);
}
void WhereId(long id_) { where_id = true; id = id_; }
void WhereParentId(long parent_id_) { where_parent_id = true; parent_id = parent_id_; }
void WhereType(Item::Type type_) { where_type = true; type = type_; }
void WhereAuth(Item::Auth st,
bool equal = true) { where_auth = true; auth = st; auth_equal = equal; }
ItemQuery()
{
sort_asc = true;
auth_equal = true;
SetAll(true, false);
id = -1;
parent_id = -1;
type = Item::none;
auth = Item::auth_none;
}
};
void GetItems(std::vector<Item> & item_table, const ItemQuery & item_query);
void GetItems(std::vector<long> & item_table, const ItemQuery & item_query);
// !! pobiera tylko jeden item (cos wymyslec innego z nazwa albo argumentem)
void GetItem(std::vector<Item> & item_table, long id);
bool GetPriv(Item & item, long id);
Error EditPrivById(Item & item, long id);
Error EditParentUrlById(Item & item, long id);
Error EditAuthById(Item & item, long id);
Error DelDirById(long id);
Error EditSubjectById(Item & item, long id);
bool DelItem(const Item & item);
void GetDirs(DirContainer & dir_table);
void GetUsers(UGContainer<User> & user_table);
void GetGroups(UGContainer<Group> & group_table);
// !! nowy interfejs
long Size(long parent_id, Item::Type type = Item::none);
Error GetItemById(long item_id, Item & item);
Error GetItem(long parent_id, const std::string & url, Item & item);
Error EditDefaultItem(long id, long new_default_item);
long GetItemId(long parent_id, const std::string & url, Item::Type type);
long GetFileId(long parent_id, const std::string & url);
long GetDirId(long parent_id, const std::string & url);
static tm ConvertTime(const char * str);
static const char * ConvertTime(const tm & t);
PGconn * GetPGconn();
virtual void Connect();
Error AddThread(Thread & thread);
Error GetThreadByDirId(long dir_id, Thread & thread);
Error GetThreads(long parent_id, std::vector<Thread> & thread_tab);
Error EditThreadAddItem(long dir_id, long item_id);
Error EditThreadRemoveItem(long dir_id);
Error RemoveThread(long dir_id);
Error GetTicketByDirId(long dir_id, Ticket & ticket);
Error GetTickets(long parent_id, std::vector<Ticket> & ticket_tab);
//bool IsTicket(long dir_id);
Error AddTicket(Ticket & ticket);
Error EditTicketById(Ticket & ticket);
Error EditTicketRemoveItem(long item_id);
Error RemoveTicket(long dir_id);
protected:
PGconn * pg_conn;
std::string db_database, db_user, db_pass;
bool close_at_end;
void SetDbParameters();
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_url);
Error EditItemInContent(Item & item);
Error EditItemGetId(Item & item);
Error EditItemGetContentId(Item & item);
void CheckAllUrlSubjectModifyItem(Item & item);
PGresult * GetItemsQuery(const ItemQuery & iq, bool skip_other_sel = false);
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, date_creation, date_modification, url, type, parent_id,
content_id, default_item, subject, content, content_type, guest_name, auth, auth_path, modification_user_id;
void SetColumns(PGresult * r);
void SetItem(PGresult * r, long row, Item & item);
};
struct TicketColumns
{
int id, dir_id, parent_id, type, status, priority, category, expected, progress, item_id;
void SetColumns(PGresult * r);
void SetTicket(PGresult * r, long row, Ticket & ticket);
};
}; // class Db
#endif

View File

@@ -1,97 +0,0 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "db.h"
void Db::ItemColumns::SetColumns(PGresult * r)
{
// PQfnumber returns -1 if there is no such a column
id = PQfnumber(r, "id");
user_id = PQfnumber(r, "user_id");
group_id = PQfnumber(r, "group_id");
privileges = PQfnumber(r, "privileges");
date_creation = PQfnumber(r, "date_creation");
date_modification = PQfnumber(r, "date_modification");
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");
guest_name = PQfnumber(r, "guest_name");
auth = PQfnumber(r, "auth");
auth_path = PQfnumber(r, "auth_path");
modification_user_id = PQfnumber(r, "modification_user_id");
}
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( date_creation != -1 ) item.date_creation = ConvertTime( Db::AssertValue(r, row, date_creation) );
if( date_modification != -1 ) item.date_modification = ConvertTime( Db::AssertValue(r, row, date_modification) );
if( url != -1 ) item.url = Db::AssertValue(r, row, url);
if( type != -1 ) item.type = static_cast<Item::Type>( atoi(Db::AssertValue(r, row, type)) );
if( 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 = static_cast<Item::ContentType>( atoi(Db::AssertValue(r, row, content_type)) );
if( guest_name != -1 ) item.guest_name = Db::AssertValue(r, row, guest_name);
if( auth != -1 ) item.auth = static_cast<Item::Auth>( atoi(Db::AssertValue(r, row, auth)) );
if( auth_path != -1 ) item.auth_path = Db::AssertValue(r, row, auth_path);
if( modification_user_id != -1 ) item.modification_user_id = atol( Db::AssertValue(r, row, modification_user_id) );
}
void Db::TicketColumns::SetColumns(PGresult * r)
{
// PQfnumber returns -1 if there is no such a column
id = PQfnumber(r, "id");
dir_id = PQfnumber(r, "dir_id");
parent_id = PQfnumber(r, "parent_id");
type = PQfnumber(r, "type");
status = PQfnumber(r, "status");
priority = PQfnumber(r, "priority");
category = PQfnumber(r, "category");
expected = PQfnumber(r, "expected");
progress = PQfnumber(r, "progress");
item_id = PQfnumber(r, "item_id");
}
void Db::TicketColumns::SetTicket(PGresult * r, long row, Ticket & ticket)
{
if( id != -1 ) ticket.id = atol( Db::AssertValue(r, row, id) );
if( dir_id != -1 ) ticket.dir_id = atol( Db::AssertValue(r, row, dir_id) );
if( parent_id != -1 ) ticket.parent_id = atol( Db::AssertValue(r, row, parent_id) );
if( type != -1 ) ticket.type = atoi( Db::AssertValue(r, row, type) );
if( status != -1 ) ticket.status = atoi( Db::AssertValue(r, row, status) );
if( priority != -1 ) ticket.priority = atoi( Db::AssertValue(r, row, priority) );
if( category != -1 ) ticket.category = atoi( Db::AssertValue(r, row, category) );
if( expected != -1 ) ticket.expected = atoi( Db::AssertValue(r, row, expected) );
if( progress != -1 ) ticket.progress = atoi( Db::AssertValue(r, row, progress) );
if( item_id != -1 ) ticket.item_id = atol( Db::AssertValue(r, row, item_id) );
}

View File

@@ -11,13 +11,15 @@
#include "log.h"
std::string DirContainer::dir_etc = "etc";
std::wstring DirContainer::dir_etc = L"etc";
std::wstring DirContainer::dir_var = L"var";
DirContainer::DirContainer()
{
is_root = false;
is_etc = false;
is_var = false;
}
@@ -40,6 +42,15 @@ return etc_iter;
}
DirContainer::Iterator DirContainer::GetVar()
{
if( !is_var )
return table.end();
return var_iter;
}
DirContainer::Iterator DirContainer::Begin()
{
return table.begin();
@@ -54,7 +65,7 @@ DirContainer::Iterator DirContainer::End()
DirContainer::SizeType DirContainer::Size()
{
return table.size();
return table.size(); // !! warning: it has O(n)
}
bool DirContainer::Empty()
@@ -63,25 +74,37 @@ bool DirContainer::Empty()
}
bool DirContainer::IsNameOfSpecialFolder(const std::wstring & name)
{
return name == dir_etc || name == dir_var;
}
// 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 = FindFirstParent(root_iter->id);
DirContainer::ParentIterator i = FindFirstChild(root_iter->id);
for( ; i!=ParentEnd() ; i = NextParent(i) )
for( ; i!=ParentEnd() ; i = NextChild(i) )
{
if( i->second->url == dir_etc )
{
is_etc = true;
etc_iter = i->second;
break;
}
else
if( i->second->url == dir_var )
{
is_var = true;
var_iter = i->second;
}
}
}
@@ -103,8 +126,16 @@ void DirContainer::CheckSpecialFolder(const Item & item, Iterator iter)
{
is_etc = true;
etc_iter = iter;
log << log1 << "DirCont: added special folder: /etc" << logend;
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;
}
}
@@ -141,10 +172,10 @@ bool DirContainer::ChangeParent(long dir_id, long new_parent_id)
if( i->parent_id == new_parent_id )
return true; // nothing to do
ParentIterator p = FindFirstParent(i->parent_id);
ParentIterator p = FindFirstChild(i->parent_id);
bool found = false;
for( ; p != table_parent.end() ; p = NextParent(p) )
for( ; p != table_parent.end() ; p = NextChild(p) )
{
if( p->second->id == dir_id )
{
@@ -157,7 +188,7 @@ bool DirContainer::ChangeParent(long dir_id, long new_parent_id)
found = true;
if( i->url == "etc" ) // !! in the future can be more special folders
if( IsNameOfSpecialFolder(i->url) )
FindSpecialFolders();
break; // that iterator (p) is only one
@@ -220,7 +251,7 @@ bool DirContainer::ParentEmpty()
}
DirContainer::ParentIterator DirContainer::FindFirstParent(long parent)
DirContainer::ParentIterator DirContainer::FindFirstChild(long parent)
{
ParentIterator i = table_parent.lower_bound(parent);
@@ -231,7 +262,7 @@ return i;
}
DirContainer::ParentIterator DirContainer::NextParent(ParentIterator i)
DirContainer::ParentIterator DirContainer::NextChild(ParentIterator i)
{
if( i == table_parent.end() )
return table_parent.end();

View File

@@ -34,6 +34,7 @@ public:
Iterator GetRoot();
Iterator GetEtc();
Iterator GetVar();
Iterator Begin();
Iterator End();
@@ -51,9 +52,10 @@ public:
ParentIterator ParentEnd();
ParentSizeType ParentSize();
bool ParentEmpty();
ParentIterator FindFirstParent(long parent);
ParentIterator NextParent(ParentIterator pi);
ParentIterator FindFirstChild(long parent);
ParentIterator NextChild(ParentIterator pi);
bool IsNameOfSpecialFolder(const std::wstring & name);
void FindSpecialFolders();
private:
@@ -75,12 +77,18 @@ private:
// etc
Iterator etc_iter;
// true if there is a var dir in the table
bool is_var;
// var
Iterator var_iter;
// indexes
TableId table_id;
TableParent table_parent;
// names of folders
static std::string dir_etc;
static std::wstring dir_etc, dir_var;
};

View File

@@ -25,9 +25,15 @@ void Dirs::SetRequest(Request * prequest)
}
void Dirs::SetNotify(Notify * pnotify)
{
notify = pnotify;
}
void Dirs::Clear()
{
dir_table.Clear();
dir_tab.Clear();
}
@@ -40,9 +46,9 @@ bool Dirs::HasReadExecAccessForRoot(const Item & item)
void Dirs::CheckRootDir()
{
DirContainer::Iterator i = dir_table.GetRoot();
DirContainer::Iterator i = dir_tab.GetRoot();
if( i != dir_table.End() )
if( i != dir_tab.End() )
{
if( !HasReadExecAccessForRoot(*i) )
{
@@ -64,13 +70,12 @@ void Dirs::CheckRootDir()
root.user_id = -1;
root.group_id = -1;
root.privileges = 0755;
root.default_item = -1;
// !! 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 )
{
dir_table.PushBack(root);
dir_tab.PushBack(root);
}
}
@@ -81,13 +86,13 @@ void Dirs::ReadDirs()
{
Clear();
db->GetDirs(dir_table);
db->GetDirs(dir_tab);
CheckRootDir();
dir_table.FindSpecialFolders();
dir_tab.FindSpecialFolders();
}
bool Dirs::ExtractName(const char * & s, std::string & name)
bool Dirs::ExtractName(const wchar_t * & s, std::wstring & name)
{
name.clear();
@@ -106,9 +111,9 @@ return !name.empty();
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 true;
@@ -116,38 +121,39 @@ return true;
bool Dirs::GetDirChilds(long parent, std::vector<Item*> & childs_table)
// !! dac clearowanie childs_tab
// !! 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) )
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) )
childs_table.push_back( &(*i->second) );
for( ; i != dir_tab.ParentEnd() ; i = dir_tab.NextChild(i) )
childs_tab.push_back( &(*i->second) );
return true;
}
DirContainer::ParentIterator Dirs::FindFirstParent(long parent_id)
DirContainer::ParentIterator Dirs::FindFirstChild(long parent_id)
{
DirContainer::ParentIterator i = dir_table.FindFirstParent(parent_id);
DirContainer::ParentIterator i = dir_tab.FindFirstChild(parent_id);
return i;
}
DirContainer::ParentIterator Dirs::NextParent(DirContainer::ParentIterator i)
DirContainer::ParentIterator Dirs::NextChild(DirContainer::ParentIterator i)
{
return dir_table.NextParent(i);
return dir_tab.NextChild(i);
}
DirContainer::ParentIterator Dirs::ParentEnd()
{
return dir_table.ParentEnd();
return dir_tab.ParentEnd();
}
@@ -155,28 +161,36 @@ DirContainer::ParentIterator Dirs::ParentEnd()
// albo tutaj stringa nie czyscic?
// O(m * log n) (m- how many parts are in 'id')
// path with a slash at the end
bool Dirs::MakePath(long id, std::string & path)
bool Dirs::MakePath(long id, std::wstring & path, bool clear_path)
{
DirContainer::Iterator i;
path = '/';
if( clear_path )
path.clear();
temp_path = '/';
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;
}
if( i->parent_id == -1 )
{
path += temp_path;
return true;
}
id = i->parent_id;
path.insert(0, i->url);
path.insert(path.begin(), '/');
temp_path.insert(0, i->url);
temp_path.insert(temp_path.begin(), '/');
}
}
@@ -184,7 +198,7 @@ DirContainer::Iterator i;
bool Dirs::ChangeParent(long dir_id, long new_parent_id)
{
return dir_table.ChangeParent(dir_id, new_parent_id);
return dir_tab.ChangeParent(dir_id, new_parent_id);
}
@@ -198,9 +212,9 @@ DirContainer::Iterator i;
while( true )
{
i = dir_table.FindId(dir_id);
i = dir_tab.FindId(dir_id);
if( i==dir_table.End() || i->parent_id==-1 )
if( i==dir_tab.End() || i->parent_id==-1 )
return false;
if( i->parent_id == parent_id )
@@ -213,11 +227,38 @@ DirContainer::Iterator i;
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()
{
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 &(*root);
@@ -226,20 +267,31 @@ return &(*root);
Item * Dirs::GetEtcDir()
{
DirContainer::Iterator etc = dir_table.GetEtc();
DirContainer::Iterator etc = dir_tab.GetEtc();
if( etc == dir_table.End() )
if( etc == dir_tab.End() )
return 0;
return &(*etc);
}
Item * Dirs::GetDir(const std::string & name, long parent)
Item * Dirs::GetVarDir()
{
DirContainer::ParentIterator i = dir_table.FindFirstParent(parent);
DirContainer::Iterator etc = dir_tab.GetVar();
for( ; i!=dir_table.ParentEnd() ; i = dir_table.NextParent(i) )
if( etc == dir_tab.End() )
return 0;
return &(*etc);
}
Item * Dirs::GetDir(const std::wstring & 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 )
return &(*i->second);
@@ -248,18 +300,18 @@ return 0;
Item * Dirs::GetDir(const std::string & path)
Item * Dirs::GetDir(const std::wstring & path)
{
DirContainer::Iterator root = dir_table.GetRoot();
DirContainer::Iterator root = dir_tab.GetRoot();
if( root == dir_table.End() )
if( root == dir_tab.End() )
// ops, we do not have a root dir
return 0;
Item * pitem = &(*root);
std::string name;
const char * s = path.c_str();
std::wstring name; // !! dodac jako skladowa klasy
const wchar_t * s = path.c_str();
while( ExtractName(s, name) )
{
@@ -269,16 +321,15 @@ Item * Dirs::GetDir(const std::string & path)
return 0;
}
return pitem;
}
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 &(*i);
@@ -289,13 +340,13 @@ return &(*i);
Item * Dirs::AddDir(const Item & item)
{
return &(*dir_table.PushBack(item));
return &(*dir_tab.PushBack(item));
}
size_t Dirs::AnalyzeDir(Item * pdir, const std::string & path, long & dir_id, std::string & dir)
size_t Dirs::AnalyzeDir(Item * pdir, const std::wstring & path, long & dir_id, std::wstring & dir)
{
size_t i = 0;
size_t old_i;
@@ -341,7 +392,7 @@ size_t Dirs::AnalyzeDir(Item * pdir, const std::string & path, long & dir_id, st
2 - the path is empty
3 - there is not such a directory
*/
int Dirs::AnalyzePath(const std::string & path, long & dir_id, std::string & dir, std::string & file)
int Dirs::AnalyzePath(const std::wstring & path, long & dir_id, std::wstring & dir, std::wstring & file)
{
Item * pdir = GetRootDir();
dir = '/';
@@ -374,10 +425,139 @@ return 0;
void Dirs::SplitPath(const std::string & path, std::string & dir, std::string & file)
// current_dir_tab can be the same container as out_dir_tab
void Dirs::CopyDirTab(const std::vector<Item*> & in, std::vector<Item*> & out)
{
std::string::size_type i;
if( &in != &out )
{
out.resize(in.size());
for(size_t i=0 ; i<in.size() ; ++i)
out[i] = in[i];
}
}
size_t Dirs::AnalyzeDir(std::vector<Item*> & dir_tab, const std::wstring & link_to)
{
if( dir_tab.empty() )
return 0;
size_t i = 0;
size_t old_i;
while( true )
{
// skipping slashes
for( ; i<link_to.size() && link_to[i] == '/' ; ++i);
if( i == link_to.size() )
return i; // 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];
Item * pdir = GetDir(analyze_temp, dir_tab.back()->id);
if( !pdir )
return old_i; // 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 = AnalyzeDir(dir_tab, 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)
*/
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();
@@ -405,12 +585,15 @@ void Dirs::SplitPath(const std::string & path, std::string & dir, std::string &
// !! dodac kasowanie z bazy
bool Dirs::DelDir(long dir_id)
{
return dir_table.DelById(dir_id);
return dir_tab.DelById(dir_id);
}
Error Dirs::AddDirectory(Item & item, bool add_to_dir_table)
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;
@@ -418,10 +601,16 @@ Error Dirs::AddDirectory(Item & item, bool add_to_dir_table)
if( status == WINIX_ERR_OK )
{
Item * pdir = AddDir(item);
Item * d = AddDir(item);
if( add_to_dir_table && request->dir_table.back()->id == item.parent_id )
request->dir_table.push_back(pdir);
if( add_to_dir_tab && !request->dir_tab.empty() && request->dir_tab.back()->id == item.parent_id )
request->dir_tab.push_back(d);
if( pdir )
*pdir = d;
if( notify_code )
notify->ItemChanged(notify_code, item);
}
return status;
@@ -429,5 +618,42 @@ 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 = -1;
v.group_id = -1;
v.privileges = 0755;
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 << '/';
}

View File

@@ -17,8 +17,9 @@
#include "item.h"
#include "dircontainer.h"
#include "db.h"
#include "db/db.h"
#include "request.h"
#include "notify/notify.h"
// we do not support '..' in a path (for simplicity and security reasons)
@@ -33,20 +34,29 @@ public:
void SetRequest(Request * prequest);
void SetDb(Db * pdb);
void SetNotify(Notify * pnotify);
// these methods return false if there is no such a dir
bool IsDir(long dir_id);
bool GetDirChilds(long parent_id, std::vector<Item*> & childs_table);
bool MakePath(long dir_id, std::string & path);
bool GetDirChilds(long parent_id, std::vector<Item*> & childs_tab); // !! zamienic na GetChilds()
bool MakePath(long dir_id, std::wstring & path, bool clear_path = true);
bool ChangeParent(long dir_id, long new_parent_id);
bool HasParent(long dir_id, long parent_id);
bool DelDir(long dir_id);
int AnalyzePath(const std::string & path, long & dir_id, std::string & dir, std::string & file);
static void SplitPath(const std::string & path, std::string & dir, std::string & file);
bool CreateDirTab(long dir_id, std::vector<Item*> & out_dir_tab);
DirContainer::ParentIterator FindFirstParent(long parent_id);
DirContainer::ParentIterator NextParent(DirContainer::ParentIterator i);
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); // !! zmienic w koncu nazwe na FindFirstChild
DirContainer::ParentIterator NextChild(DirContainer::ParentIterator i);
DirContainer::ParentIterator ParentEnd();
@@ -54,28 +64,37 @@ public:
// !! zmienic nazwy wskazujace ze operujemy tylko na lokalnej tablicy
Item * GetRootDir();
Item * GetEtcDir();
Item * GetDir(const std::string & name, long parent);
Item * GetDir(const std::string & path);
Item * GetVarDir();
Item * GetDir(const std::wstring & name, long parent);
Item * GetDir(const std::wstring & path);
Item * GetDir(long id);
Item * AddDir(const Item & item);
void CheckRootDir();
Item * CreateVarDir();
// !! jak juz wczesniejsze nazwy beda zmienione to tutaj damy AddDir()
Error AddDirectory(Item & item, bool add_to_dir_table = false);
// !! 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);
private:
Request * request;
Db * db;
Notify * notify;
DirContainer dir_table;
DirContainer dir_tab;
std::wstring temp_path;
std::wstring temp_link_to;
size_t AnalyzeDir(Item * pdir, const std::string & path, long & dir_id, std::string & dir);
std::string analyze_temp;
size_t AnalyzeDir(Item * pdir, const std::wstring & path, long & dir_id, std::wstring & dir);
size_t AnalyzeDir(std::vector<Item*> & dir_tab, const std::wstring & link_to);
std::wstring analyze_temp;
bool ExtractName(const char * & s, std::string & name);
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);
};

View File

@@ -55,7 +55,6 @@
#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
@@ -70,6 +69,8 @@
//#define WINIX_ERR_UNKNOWN 1000
#define WINIX_NOTHING_TO_DO 109
typedef int Error;

View File

@@ -12,13 +12,17 @@
#include "httpsimpleparser.h"
#include "requesttypes.h"
#include "misc.h"
#include "utf8.h"
class GetParser : public HttpSimpleParser
{
const char * get_string;
GetTable & get_table;
GetTab * get_tab;
std::wstring temp;
bool input_as_utf8;
protected:
@@ -33,22 +37,47 @@ protected:
virtual void Parameter(std::string &, std::string & value)
{
get_table.push_back(value);
log << log2 << "Get, value: \"" << value << "\"" << logend;
if( input_as_utf8 )
Ezc::UTF8ToWide(value, temp);
else
AssignString(value, temp);
get_tab->push_back(temp);
log << log2 << "Get, value: \"" << temp << "\"" << logend;
}
public:
GetParser(const char * get_string_, GetTable & get_table_) : get_string(get_string_), get_table(get_table_)
GetParser()
{
HttpSimpleParser::separator = '/';
HttpSimpleParser::read_name = false;
if( get_string && *get_string == separator ) // one '/' at the beginning
input_as_utf8 = false;
}
void UTF8(bool utf)
{
input_as_utf8 = utf;
}
// get_string_ can be null
void Parse(const char * get_string_, GetTab & get_tab_)
{
get_string = get_string_;
get_tab = &get_tab_;
if( get_string && *get_string == separator )
{
// skipping one '/' at the beginning
++get_string;
}
HttpSimpleParser::Parse();
}
};

View File

@@ -18,7 +18,7 @@
struct Group
{
long id;
std::string name; // group name
std::wstring name; // group name
std::vector<long> members; // users id
Group()

View File

@@ -43,7 +43,7 @@ return &(*i);
}
Group * Groups::GetGroup(const std::string & name)
Group * Groups::GetGroup(const std::wstring & name)
{
Table::Iterator i = table.FindName(name);
@@ -54,7 +54,7 @@ return &(*i);
}
long Groups::GetGroupId(const std::string & name)
long Groups::GetGroupId(const std::wstring & name)
{
Group * pgroup = GetGroup(name);

View File

@@ -14,7 +14,7 @@
#include "group.h"
#include "ugcontainer.h"
#include "db.h"
#include "db/db.h"
@@ -33,8 +33,8 @@ public:
void Clear();
void ReadGroups(Db * db);
Group * GetGroup(long group_id);
Group * GetGroup(const std::string & name);
long GetGroupId(const std::string & name);
Group * GetGroup(const std::wstring & name);
long GetGroupId(const std::wstring & name);
Iterator Begin();
Iterator End();
SizeType Size();

View File

@@ -27,7 +27,7 @@ HTMLFilter::Item::Item()
void HTMLFilter::Filter(const char * in, std::string & out)
void HTMLFilter::Filter(const wchar_t * in, std::wstring & out)
{
pchar = in;
stack_len = 0;
@@ -53,9 +53,13 @@ void HTMLFilter::Deinit()
void HTMLFilter::Filter(const std::string & in, std::string & out)
void HTMLFilter::Filter(const std::wstring & in, std::wstring & out)
{
out.reserve(in.size() * 2 + 1);
size_t out_projected_len = in.size() * 2 + 1;
if( out.capacity() < out_projected_len )
out.reserve(out_projected_len);
Filter(in.c_str(), out);
}
@@ -63,7 +67,7 @@ void HTMLFilter::Filter(const std::string & in, std::string & out)
HTMLFilter::HTMLFilter()
{
pstack = new Item[WINIX_HTMLFILTER_STACK_MAXLEN];
buffer = new char[WINIX_HTMLFILTER_BUFFER_MAXLEN];
buffer = new wchar_t[WINIX_HTMLFILTER_BUFFER_MAXLEN];
tab_size = 2;
trim_white = false;
@@ -78,7 +82,7 @@ HTMLFilter::HTMLFilter(const HTMLFilter & f)
{
// don't need to copy the stack
pstack = new Item[WINIX_HTMLFILTER_STACK_MAXLEN];
buffer = new char[WINIX_HTMLFILTER_BUFFER_MAXLEN];
buffer = new wchar_t[WINIX_HTMLFILTER_BUFFER_MAXLEN];
}
@@ -86,7 +90,7 @@ HTMLFilter & HTMLFilter::operator=(const HTMLFilter & f)
{
// don't need to copy the stack
pstack = new Item[WINIX_HTMLFILTER_STACK_MAXLEN];
buffer = new char[WINIX_HTMLFILTER_BUFFER_MAXLEN];
buffer = new wchar_t[WINIX_HTMLFILTER_BUFFER_MAXLEN];
return *this;
}
@@ -226,7 +230,7 @@ void HTMLFilter::SkipWhiteWithFirstNewLine()
void HTMLFilter::CheckNewLine()
{
const char * start = pchar;
const wchar_t * start = pchar;
SkipWhite();
last_new_line = (*pchar==10);
@@ -269,7 +273,7 @@ return false;
// used for such tags as: script, pre, textarea
void HTMLFilter::PutLastTagWithClosingTag()
{
const char * start = pchar;
const wchar_t * start = pchar;
while( *pchar != 0 )
@@ -296,9 +300,9 @@ const char * start = pchar;
const char * HTMLFilter::SkipItemCheckXmlSimple()
const wchar_t * HTMLFilter::SkipItemCheckXmlSimple()
{
const char * end = pchar;
const wchar_t * end = pchar;
while( *pchar!=0 )
@@ -361,7 +365,7 @@ size_t i;
void HTMLFilter::Put(const char * str, const char * end)
void HTMLFilter::Put(const wchar_t * str, const wchar_t * end)
{
if( str>=end )
return;
@@ -372,22 +376,22 @@ void HTMLFilter::Put(const char * str, const char * end)
int HTMLFilter::CheckOrphan(const char * str, const char * end, const char * orphan)
int HTMLFilter::CheckOrphan(const wchar_t * str, const wchar_t * end, const wchar_t * orphan)
{
size_t res;
for( ; str<end && *orphan!=0 ; ++str, ++orphan )
{
res = ToLower(*(unsigned const char*)str) - ToLower(*(unsigned const char*)orphan);
res = ToLower(*str) - ToLower(*orphan);
if( res != 0 )
return res;
}
if( str < end )
return ToLower(*(unsigned const char*)str);
return ToLower(*str);
return -ToLower(*(unsigned const char*)orphan);
return -int(ToLower(*orphan));
}
@@ -395,7 +399,7 @@ return -ToLower(*(unsigned const char*)orphan);
// binary search in table
// o1 - index of the first element
// o2 - index of the last element
bool HTMLFilter::CheckOrphanTable(const char * str, const char * end, const char ** table, size_t o1, size_t o2)
bool HTMLFilter::CheckOrphanTable(const wchar_t * str, const wchar_t * end, const wchar_t ** table, size_t o1, size_t o2)
{
int res;
@@ -435,19 +439,33 @@ return false;
}
bool HTMLFilter::CheckOrphanLangPl(const char * str, const char * end)
bool HTMLFilter::CheckOrphanLangPl(const wchar_t * str, const wchar_t * end)
{
// the table must be sorted in alphabetical order
// polish letters coded in iso-8859-2
static const char * orphans[] = {
"(np.", "s.", "a", "ale", "bo", "by", "co", "czy", "do", "go", "i",
"ich", "ja", "je", "jej", "jest", "ju¿", "", "ku", "li", "mi", "na",
"nie", "np.", "nr", "o", "od", "po", "", "ta", "to", "tu", "",
"", "u", "w", "we", "wy", "z", "za", "ze", "¿e", "ów"
// !! wymieniæ na unikode
/*
tak jak bylo oryginalnie (tylko bez L):
static const wchar_t * orphans[] = {
L"(np.", L"s.", L"a", L"ale", L"bo", L"by", L"co", L"czy", L"do", L"go", L"i",
L"ich", L"ja", L"je", L"jej", L"jest", L"ju¿", L"j±", L"ku", L"li", L"mi", L"na",
L"nie", L"np.", L"nr", L"o", L"od", L"po", L"s±", L"ta", L"to", L"tu", L"t±",
L"tê", L"u", L"w", L"we", L"wy", L"z", L"za", L"ze", L"¿e", L"ów"
};
*/
static const wchar_t * orphans[] = {
L"(np.", L"s.", L"a", L"ale", L"bo", L"by", L"co", L"czy", L"do", L"go", L"i",
L"ich", L"ja", L"je", L"jej", L"jest", L"juz", L"ja", L"ku", L"li", L"mi", L"na",
L"nie", L"np.", L"nr", L"o", L"od", L"po", L"sa", L"ta", L"to", L"tu", L"ta",
L"te", L"u", L"w", L"we", L"wy", L"z", L"za", L"ze", L"ze", L"ow"
};
size_t o1 = 0;
size_t o2 = sizeof(orphans) / sizeof(const char*) - 1;
size_t o2 = sizeof(orphans) / sizeof(const wchar_t*) - 1;
return CheckOrphanTable(str, end, orphans, o1, o2);
}
@@ -455,21 +473,21 @@ return CheckOrphanTable(str, end, orphans, o1, o2);
// SK i CZ
bool HTMLFilter::CheckOrphanLangCz(const char * str, const char * end)
bool HTMLFilter::CheckOrphanLangCz(const wchar_t * str, const wchar_t * end)
{
// the table must be sorted in alphabetical order
static const char * orphans[] = {
"a", "i", "k", "o", "s", "u", "v", "z"
static const wchar_t * orphans[] = {
L"a", L"i", L"k", L"o", L"s", L"u", L"v", L"z"
};
size_t o1 = 0;
size_t o2 = sizeof(orphans) / sizeof(const char*) - 1;
size_t o2 = sizeof(orphans) / sizeof(const wchar_t*) - 1;
return CheckOrphanTable(str, end, orphans, o1, o2);
}
bool HTMLFilter::CheckOrphan(const char * str, const char * end)
bool HTMLFilter::CheckOrphan(const wchar_t * str, const wchar_t * end)
{
if( str == end || lang == lang_none )
return false;
@@ -482,9 +500,9 @@ return CheckOrphanLangPl(str, end);
size_t HTMLFilter::PutNormalTextFillBuffer(const char * & str, const char * & end)
size_t HTMLFilter::PutNormalTextFillBuffer(const wchar_t * & str, const wchar_t * & end)
{
const char * word = str; // pointing at the beginning of a word
const wchar_t * word = str; // pointing at the beginning of a word
size_t i = 0;
// some space in the buffer for non break spaces (orphans) and spaces at the beginning of a line
size_t epsilon = WINIX_HTMLFILTER_BUFFER_MAXLEN / 10 + 1;
@@ -552,9 +570,9 @@ return i;
}
size_t HTMLFilter::PutNormalTextTrimFillBuffer(const char * & str, const char * & end)
size_t HTMLFilter::PutNormalTextTrimFillBuffer(const wchar_t * & str, const wchar_t * & end)
{
const char * word = str; // pointint at the beginning of a word
const wchar_t * word = str; // pointint at the beginning of a word
size_t non_whites = 0;
size_t i = 0;
bool is_white;
@@ -608,7 +626,7 @@ return i;
void HTMLFilter::PutNormalText(const char * str, const char * end)
void HTMLFilter::PutNormalText(const wchar_t * str, const wchar_t * end)
{
size_t buf_len;
@@ -620,7 +638,7 @@ size_t buf_len;
}
void HTMLFilter::PutNormalTextTrim(const char * str, const char * end)
void HTMLFilter::PutNormalTextTrim(const wchar_t * str, const wchar_t * end)
{
size_t buf_len;
@@ -646,23 +664,23 @@ void HTMLFilter::PutClosingTagMark()
void HTMLFilter::PutTagName(const char * name)
void HTMLFilter::PutTagName(const wchar_t * name)
{
(*out_string) += name;
}
bool HTMLFilter::IsTagSafe(const char * tag)
bool HTMLFilter::IsTagSafe(const wchar_t * tag)
{
if( !safe_mode )
return true;
static const char * unsafe_tags[] = {
"script", "iframe", "frame", "frameset",
"applet", "head", "meta", "html", "link", "body"
static const wchar_t * unsafe_tags[] = {
L"script", L"iframe", L"frame", L"frameset",
L"applet", L"head", L"meta", L"html", L"link", L"body"
};
size_t len = sizeof(unsafe_tags) / sizeof(const char*);
size_t len = sizeof(unsafe_tags) / sizeof(const wchar_t*);
size_t i;
for(i=0 ; i<len ; ++i)
@@ -679,7 +697,7 @@ return true;
// start, end - arguments
void HTMLFilter::PutOpeningTag(const char * start, const char * end)
void HTMLFilter::PutOpeningTag(const wchar_t * start, const wchar_t * end)
{
if( !IsTagSafe(LastItem().name) )
return;
@@ -698,7 +716,7 @@ void HTMLFilter::PutOpeningTag(const char * start, const char * end)
void HTMLFilter::PutClosingTag(const char * tag)
void HTMLFilter::PutClosingTag(const wchar_t * tag)
{
if( !IsTagSafe(tag) )
return;
@@ -739,8 +757,8 @@ size_t i = 0;
if( orphan_mode == orphan_nbsp )
{
static const char nb[] = "&nbsp;";
size_t len = sizeof(nb) / sizeof(char) - 1; // '0' at the end
static const wchar_t nb[] = L"&nbsp;";
size_t len = sizeof(nb) / sizeof(wchar_t) - 1; // '0' at the end
if( index+len < WINIX_HTMLFILTER_BUFFER_MAXLEN-1 )
{
@@ -753,7 +771,7 @@ size_t i = 0;
if( index+1 < WINIX_HTMLFILTER_BUFFER_MAXLEN-1 )
{
i = 1;
buffer[index] = (char)160;
buffer[index] = (wchar_t)160;
}
}
@@ -799,8 +817,8 @@ bool HTMLFilter::IsClosingXmlSimpleTagMark()
bool HTMLFilter::IsOpeningCommentaryTagMark()
{
static char comm_open[] = "<!--";
size_t comm_open_len = sizeof(comm_open) / sizeof(char) - 1;
static wchar_t comm_open[] = L"<!--";
size_t comm_open_len = sizeof(comm_open) / sizeof(wchar_t) - 1;
return IsNameEqual(pchar, comm_open, comm_open_len);
}
@@ -816,8 +834,8 @@ size_t HTMLFilter::OpeningCommentaryTagMarkSize()
// skipping the commentary tag if exists
bool HTMLFilter::SkipCommentaryTagIfExists()
{
static char comm_close[] = "-->";
size_t comm_close_len = sizeof(comm_close) / sizeof(char) - 1;
static wchar_t comm_close[] = L"-->";
size_t comm_close_len = sizeof(comm_close) / sizeof(wchar_t) - 1;
if( !IsOpeningCommentaryTagMark() )
return false;
@@ -837,7 +855,7 @@ return true;
}
void HTMLFilter::ReadNormalTextSkipWhite(const char * & start, const char * & last_non_white)
void HTMLFilter::ReadNormalTextSkipWhite(const wchar_t * & start, const wchar_t * & last_non_white)
{
if( trim_white )
{
@@ -875,8 +893,8 @@ void HTMLFilter::ReadNormalTextSkipWhite(const char * & start, const char * & la
// reading text between html tags
void HTMLFilter::ReadNormalText()
{
const char * start = pchar;
const char * last_non_white = pchar;
const wchar_t * start = pchar;
const wchar_t * last_non_white = pchar;
if( last_new_line )
ReadNormalTextSkipWhite(start, last_non_white);
@@ -912,7 +930,7 @@ const char * last_non_white = pchar;
// start, end - parameters to a tag
void HTMLFilter::PrintItem(const char * start, const char * end)
void HTMLFilter::PrintItem(const wchar_t * start, const wchar_t * end)
{
if( last_new_line )
{
@@ -930,7 +948,7 @@ void HTMLFilter::PrintItem(const char * start, const char * end)
bool HTMLFilter::ReadItem()
{
const char * start = pchar;
const wchar_t * start = pchar;
if( *pchar == 0 )
return false;
@@ -956,7 +974,7 @@ const char * start = pchar;
if( LastItem().type != Item::closing )
LastItem().type = (LastItem().name[0] == '!') ? Item::special : Item::opening;
const char * end = SkipItemCheckXmlSimple();
const wchar_t * end = SkipItemCheckXmlSimple();
if( LastItem().type != Item::closing )
PrintItem(start, end);
@@ -969,7 +987,7 @@ return true;
int HTMLFilter::ToLower(int c)
wchar_t HTMLFilter::ToLower(wchar_t c)
{
if( c>='A' && c<='Z' )
return c - 'A' + 'a';
@@ -978,7 +996,7 @@ return c;
}
bool HTMLFilter::IsNameEqual(const char * name1, const char * name2)
bool HTMLFilter::IsNameEqual(const wchar_t * name1, const wchar_t * name2)
{
for( ; *name1!=0 && *name2!=0 ; ++name1, ++name2 )
if( ToLower(*name1) != ToLower(*name2) )
@@ -993,7 +1011,7 @@ return false;
// len characters from both strings must be equal
bool HTMLFilter::IsNameEqual(const char * name1, const char * name2, size_t len)
bool HTMLFilter::IsNameEqual(const wchar_t * name1, const wchar_t * name2, size_t len)
{
for( ; *name1!=0 && *name2!=0 && len>0 ; ++name1, ++name2, --len )
if( ToLower(*name1) != ToLower(*name2) )
@@ -1007,9 +1025,9 @@ return false;
bool HTMLFilter::IsLastTag(const char * name)
bool HTMLFilter::IsLastTag(const wchar_t * name)
{
const char * tag = LastItem().name;
const wchar_t * tag = LastItem().name;
return IsNameEqual(name, tag);
}
@@ -1019,13 +1037,14 @@ bool HTMLFilter::IsLastTag(const char * name)
// checking exceptions for opening tags
void HTMLFilter::CheckExceptions()
{
if( IsLastTag("meta") ||
IsLastTag("input") ||
IsLastTag("br") ||
IsLastTag("hr") ||
IsLastTag("img") ||
IsLastTag("link") ||
IsLastTag("area") )
if( IsLastTag(L"meta") ||
IsLastTag(L"input") ||
IsLastTag(L"br") ||
IsLastTag(L"hr") ||
IsLastTag(L"img") ||
IsLastTag(L"link") ||
IsLastTag(L"param") ||
IsLastTag(L"area") )
{
LastItem().type = Item::simple;
PopStack();
@@ -1033,10 +1052,10 @@ void HTMLFilter::CheckExceptions()
}
// in safe_mode the script tag is ignored
if( !safe_mode && IsLastTag("script") )
if( !safe_mode && IsLastTag(L"script") )
PutLastTagWithClosingTag();
if( IsLastTag("pre") || IsLastTag("textarea") )
if( IsLastTag(L"pre") || IsLastTag(L"textarea") )
PutLastTagWithClosingTag();
}
@@ -1137,7 +1156,11 @@ void HTMLFilter::CheckClosingTags()
bool HTMLFilter::PrintRest()
{
const char * start = pchar;
const wchar_t * start = pchar;
// in safe mode we do not print the rest html code
if( safe_mode )
return false;
while( *pchar )
++pchar;

View File

@@ -72,8 +72,8 @@ public:
// main methods used for filtering
void Filter(const char * in, std::string & out);
void Filter(const std::string & in, std::string & out);
void Filter(const wchar_t * in, std::wstring & out);
void Filter(const std::wstring & in, std::wstring & out);
// insert a white space into long lines
@@ -114,7 +114,7 @@ protected:
struct Item
{
char name[WINIX_HTMLFILTER_ITEM_MAXLEN];
wchar_t name[WINIX_HTMLFILTER_ITEM_MAXLEN];
size_t name_len;
enum Type
@@ -135,24 +135,24 @@ protected:
// only this method have direct access to the output string
// you can easily change the output from a std::string to something else
virtual void Put(const char * str, const char * end);
// you can easily change the output from a std::wstring to something else
virtual void Put(const wchar_t * str, const wchar_t * end);
Item & GetItem(size_t i);
Item & LastItem();
int ToLower(int c);
bool IsNameEqual(const char * name1, const char * name2);
bool IsNameEqual(const char * name1, const char * name2, size_t len);
bool IsLastTag(const char * name);
bool IsTagSafe(const char * tag);
wchar_t ToLower(wchar_t c);
bool IsNameEqual(const wchar_t * name1, const wchar_t * name2);
bool IsNameEqual(const wchar_t * name1, const wchar_t * name2, size_t len);
bool IsLastTag(const wchar_t * name);
bool IsTagSafe(const wchar_t * tag);
int CheckOrphan(const char * str, const char * end, const char * orphan);
bool CheckOrphanTable(const char * str, const char * end, const char ** table, size_t o1, size_t o2);
bool CheckOrphanLangPl(const char * str, const char * end);
bool CheckOrphanLangCz(const char * str, const char * end);
bool CheckOrphan(const char * str, const char * end);
int CheckOrphan(const wchar_t * str, const wchar_t * end, const wchar_t * orphan);
bool CheckOrphanTable(const wchar_t * str, const wchar_t * end, const wchar_t ** table, size_t o1, size_t o2);
bool CheckOrphanLangPl(const wchar_t * str, const wchar_t * end);
bool CheckOrphanLangCz(const wchar_t * str, const wchar_t * end);
bool CheckOrphan(const wchar_t * str, const wchar_t * end);
bool IsWhite(int c);
void SkipWhite();
@@ -165,7 +165,7 @@ protected:
virtual bool IsClosingTagMark();
virtual bool IsClosingXmlSimpleTagMark();
bool SkipCommentaryTagIfExists();
const char * SkipItemCheckXmlSimple();
const wchar_t * SkipItemCheckXmlSimple();
void PopStack();
bool PushStack();
@@ -175,37 +175,37 @@ protected:
void CheckStackPrintRest();
void AddForgottenTags();
void CheckClosingTags();
virtual void ReadNormalTextSkipWhite(const char * & start, const char * & last_non_white);
virtual void ReadNormalTextSkipWhite(const wchar_t * & start, const wchar_t * & last_non_white);
void ReadNormalText();
bool PrintRest();
void PrintItem(const char * start, const char * end);
void PrintItem(const wchar_t * start, const wchar_t * end);
void ReadItemName();
bool ReadItem();
virtual void Init();
virtual void Deinit();
void Read();
size_t PutNormalTextTrimFillBuffer(const char * & str, const char * & end);
size_t PutNormalTextFillBuffer(const char * & str, const char * & end);
virtual void PutNormalText(const char * str, const char * end);
virtual void PutNormalTextTrim(const char * str, const char * end);
size_t PutNormalTextTrimFillBuffer(const wchar_t * & str, const wchar_t * & end);
size_t PutNormalTextFillBuffer(const wchar_t * & str, const wchar_t * & end);
virtual void PutNormalText(const wchar_t * str, const wchar_t * end);
virtual void PutNormalTextTrim(const wchar_t * str, const wchar_t * end);
void PutLastTagWithClosingTag();
virtual void PutOpeningTagMark();
virtual void PutClosingTagMark();
virtual void PutTagName(const char * name);
virtual void PutOpeningTag(const char * start, const char * end);
virtual void PutClosingTag(const char * tag);
virtual void PutTagName(const wchar_t * name);
virtual void PutOpeningTag(const wchar_t * start, const wchar_t * end);
virtual void PutClosingTag(const wchar_t * tag);
size_t PutTabsToBuffer(size_t index, size_t len);
size_t PutNonBreakSpaceToBuffer(size_t index);
void PutTabs(size_t len);
void PutNewLine();
const char * pchar;
const wchar_t * pchar;
Item empty;
Item * pstack; // stack pointer
size_t stack_len; // length of the stack
char * buffer; // buffer used when printing
std::string * out_string;
wchar_t * buffer; // buffer used when printing
std::wstring * out_string;
bool last_new_line;
size_t break_after; // insert a space into long lines after break_after characters
bool trim_white; // trimming white characters

View File

@@ -46,7 +46,7 @@ protected:
void TrimWhiteChars(std::string & s);
void CheckSpecialChar();
void Parse();
public:
@@ -60,12 +60,6 @@ public:
skip_white_chars = false;
recognize_special_chars = true;
}
void Parse();
};

72
core/item.cpp Executable file
View File

@@ -0,0 +1,72 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "item.h"
#include "misc.h"
Item::Item()
{
Clear();
}
void Item::SetDateToNow()
{
date_creation = Time(std::time(0));
date_modification = date_creation;
}
void Item::SetDateModifyToNow()
{
date_modification = Time(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;
has_thumb = false;
html_template.clear();
SetDateToNow();
}

View File

@@ -13,6 +13,12 @@
#include <string>
#define WINIX_ITEM_FILETYPE_NONE 0
#define WINIX_ITEM_FILETYPE_IMAGE 1
#define WINIX_ITEM_FILETYPE_DOCUMENT 2
#define WINIX_ITEM_FILETYPE_UNKNOWN 3
struct Item
@@ -23,7 +29,7 @@ long parent_id;
long user_id;
long group_id;
std::string guest_name; // used as a user name when user_id is equal -1
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)
@@ -32,10 +38,11 @@ int privileges;
tm date_creation;
tm date_modification;
std::string subject;
std::string content;
long content_id; // used by the database
std::string url;
std::wstring subject;
std::wstring content;
std::wstring url;
int modify_index;
enum ContentType
{
@@ -54,90 +61,44 @@ enum Type
{
dir = 0,
file = 1,
symlink = 2,
none = 1000 // !! pozbyc sie tego
none = 1000
};
Type type;
long default_item;
// used when type is symlink or to a directory too (function 'default')
std::wstring link_to;
int link_redirect;
// 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;
// external static file authorized by winix
enum Auth
{
auth_none = 0, /* there is not an external file */
auth_image = 1, /* png, gif, jpg - only types available to render by a web browser*/
auth_document = 2, /* pdf doc xls txt */
auth_other = 3 /* other file */
};
Auth auth;
std::string auth_path; // path to a file (if auth!=auth_none)
// methods
Item()
{
Clear();
}
void SetDateToNow()
{
time_t t = std::time(0);
date_creation = *std::localtime( &t );
date_modification = date_creation;
}
void SetDateModifyToNow()
{
time_t t = std::time(0);
date_modification = *std::localtime( &t );
}
void Clear()
{
id = -1;
user_id = -1;
group_id = -1;
privileges = 0;
modification_user_id = -1;
guest_name.clear();
subject.clear();
content.clear();
url.clear();
content_type = ct_formatted_text;
type = none;
parent_id = -1;
default_item = -1;
content_id = -1;
auth = auth_none;
auth_path.clear();
SetDateToNow();
}
std::wstring html_template;
// 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 class DbItemColumns;
};

View File

@@ -10,7 +10,7 @@
#include "lastcontainer.h"
#include "log.h"
#include "misc.h"
LastItem::LastItem()
@@ -68,7 +68,7 @@ return last_tab.end();
void LastContainer::UserLogin(long user_id, const std::string & name, unsigned int ip, long session_id)
void LastContainer::UserLogin(long user_id, const std::wstring & name, unsigned int ip, long session_id)
{
LastTab::iterator i = FindNotLoggedOut(user_id, session_id);
@@ -78,7 +78,7 @@ LastTab::iterator i = FindNotLoggedOut(user_id, session_id);
return;
}
if( last_tab.size() >= LAST_TABLE_SIZE )
if( last_tab.size() >= LAST_TABLE_SIZE ) // last_tab has O(n) complexity
last_tab.erase(last_tab.begin());
LastItem li;
@@ -87,9 +87,7 @@ LastTab::iterator i = FindNotLoggedOut(user_id, session_id);
li.name = name;
li.ip = ip;
li.session_id = session_id;
time_t t = std::time(0);
li.start = *localtime(&t);
li.start = Time(std::time(0));
last_tab.insert(last_tab.end(), li);
@@ -105,8 +103,7 @@ LastTab::iterator i = FindNotLoggedOut(user_id, session_id);
if( i != last_tab.end() )
{
time_t t = std::time(0);
i->end = *localtime(&t);
i->end = Time(std::time(0));
}
else
{

View File

@@ -28,7 +28,7 @@ struct LastItem
// additional we store the whole string-name
// (you can delete a user from the database but we can still print the name)
std::string name;
std::wstring name;
// ip address
unsigned int ip;
@@ -62,7 +62,7 @@ public:
Iterator Begin();
Iterator End();
void UserLogin(long user_id, const std::string & name, unsigned int ip, long session_id);
void UserLogin(long user_id, const std::wstring & name, unsigned int ip, long session_id);
void UserLogout(long user_id, long session_id);

View File

@@ -10,38 +10,54 @@
#include "log.h"
#include <ctime>
#include <string.h>
#include "utf8.h"
Log::Log()
{
log_level = 3;
current_level = 4; // nothing to log (call Init() first)
item = 0;
item_save = 1;
log_level = 1;
current_level = 100; // nothing to log (call Init() first)
request = 0;
max_requests = 1;
lines = 0;
max_lines = 5000;
log_file_open = false;
}
void Log::Init(int log_l, const std::string & log_f, bool log_std, int log_request)
Log::~Log()
{
log_level = log_l;
log_file = log_f;
log_stdout = log_std;
item_save = log_request;
SaveLogAndClear();
}
OpenFile();
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::PutDate(Manipulators m)
{
// logs are related to localtime
time_t t = std::time(0);
std::tm * loct = std::localtime(&t);
@@ -57,10 +73,22 @@ void Log::PutDate(Manipulators m)
}
Log & Log::operator<<(const void * s)
{
if( current_level > log_level )
return *this;
buffer << s;
return *this;
}
Log & Log::operator<<(const char * s)
{
if( current_level > log_level )
return *this;
if( !s )
return *this;
@@ -73,8 +101,10 @@ return *this;
Log & Log::operator<<(const std::string & s)
{
buffer << s;
if( current_level > log_level )
return *this;
buffer << s;
return *this;
}
@@ -82,23 +112,63 @@ Log & Log::operator<<(const std::string & s)
Log & Log::operator<<(const std::string * s)
{
buffer << *s;
if( current_level > log_level )
return *this;
buffer << *s;
return *this;
}
Log & Log::operator<<(const void * s)
Log & Log::operator<<(const wchar_t * s)
{
buffer << 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)
{
buffer << s;
if( current_level <= log_level )
{
buffer << s;
}
return *this;
}
@@ -107,7 +177,10 @@ Log & Log::operator<<(int s)
Log & Log::operator<<(long s)
{
buffer << s;
if( current_level <= log_level )
{
buffer << s;
}
return *this;
}
@@ -117,7 +190,10 @@ Log & Log::operator<<(long s)
Log & Log::operator<<(char s)
{
buffer << s;
if( current_level <= log_level )
{
buffer << s;
}
return *this;
}
@@ -126,7 +202,10 @@ Log & Log::operator<<(char s)
Log & Log::operator<<(size_t s)
{
buffer << s;
if( current_level <= log_level )
{
buffer << s;
}
return *this;
}
@@ -135,7 +214,10 @@ Log & Log::operator<<(size_t s)
Log & Log::operator<<(double s)
{
buffer << s;
if( current_level <= log_level )
{
buffer << s;
}
return *this;
}
@@ -147,27 +229,23 @@ Log & Log::operator<<(Manipulators m)
switch(m)
{
case logend:
buffer << '\n';
lines += 1;
break;
if( current_level <= log_level )
{
buffer << '\n';
lines += 1;
case logsavenow:
SaveLog();
buffer.str( "" );
item = 0;
lines = 0;
if( save_each_line )
SaveLogAndClear();
}
break;
case logsave:
item += 1;
SaveLogAndClear();
break;
if( item >= item_save || lines > 3000 )
{
SaveLog();
buffer.str( "" );
item = 0;
lines = 0;
}
case logendrequest:
if( ++request >= max_requests || lines > max_lines )
SaveLogAndClear();
break;
case log1:
@@ -181,6 +259,10 @@ Log & Log::operator<<(Manipulators m)
case log3:
current_level = 3;
break;
case log4:
current_level = 4;
break;
}
return *this;
@@ -198,23 +280,28 @@ void Log::SystemErr(int err)
}
void Log::SaveLogAndClear()
{
SaveLog();
buffer.Clear();
request = 0;
lines = 0;
}
void Log::SaveLog()
{
if( current_level > log_level )
return;
const std::string & source = buffer.str();
if( source.empty() )
if( buffer.Str().empty() )
return;
if( log_stdout )
std::cout << source;
Ezc::WideToUTF8(buffer.Str(), std::cout);
if( log_file.empty() )
return;
if( !file )
if( !log_file_open || !file )
{
file.close();
file.clear();
@@ -225,7 +312,8 @@ void Log::SaveLog()
return;
}
file << source << std::endl;
Ezc::WideToUTF8(buffer.Str(), file);
file.flush();
}

View File

@@ -15,37 +15,36 @@
#include <fstream>
#include <iostream>
#include <string>
#include "textstream.h"
// !! dodac manipulator logsave, logi zostana zapisane pod koniec wykonywania jednego requesta (albo po kilku w zaleznosci od jakiejs opcji w konfigu)
// logsave zostanie wywolane w requestcontroller.cpp przy konczeniu wykonywania requesta
enum Manipulators { logsave, logsavenow, logend, log1, log2, log3 };
// 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
enum Manipulators { log1, log2, log3, log4, logend, logendrequest, logsave };
class Log
{
std::ostringstream buffer;
int log_level, current_level;
int item, item_save;
std::string log_file;
bool log_stdout;
std::ofstream file;
int lines;
void OpenFile();
public:
Log();
void Init(int log_l, const std::string & log_f, bool log_std, int log_request);
~Log();
void Init(int log_level_, bool save_each_line_, const std::string & log_file_, bool log_std, int log_max_requests);
void PutDate(Manipulators m);
Log & operator<<(const char * s);
Log & operator<<(const void * s);
Log & operator<<(const char * 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<<(long s);
Log & operator<<(char s);
@@ -54,8 +53,49 @@ public:
Log & operator<<(Manipulators m);
void SystemErr(int err);
void SaveLog();
void SaveLogAndClear();
private:
// 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();
};

File diff suppressed because it is too large Load Diff

View File

@@ -14,63 +14,417 @@
#include <string>
#include <sstream>
#include <ctime>
#include "item.h"
#include <cstdio>
#include "item.h"
void ToString(std::string & s, int value);
void ToString(std::string & s, long value);
int ChangeLocalChar(unsigned char c);
bool CorrectUrlChar(char c);
void CorrectUrlDots(std::string & url);
void CorrectUrlChars(std::string & url);
void CorrectUrlOnlyAllowedChar(std::string & url);
/*
conversions between text and numbers
*/
void HtmlEscape(std::ostringstream & out, const std::string & in);
void HtmlEscapeFormTxt(std::ostringstream & out, const std::string & in);
std::string HtmlEscape(const std::string & in);
std::string HtmlEscapeFormTxt(const std::string & in);
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);
const char * DateToStr(int year, int month, int day);
const char * DateToStr(int year, int month, int day, int hour, int min, int sec);
const char * DateToStr(tm * ptm);
const char * DateToStr(time_t t);
const char * DateToStrWithoutHours(tm * ptm);
const char * DateToStrWithoutHours(time_t t);
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);
// if the buffer is too small it will be terminated at the beginning (empty string)
// and the function returns false
template<class CharType>
bool Toa(unsigned long value, CharType * buffer, size_t buf_len, int base = 10)
{
size_t i1, i2;
long rest;
if( buf_len == 0 )
return false;
i1 = i2 = 0;
if( base < 2 ) base = 2;
if( base > 16 ) base = 16;
do
{
rest = value % base;
value = value / base;
buffer[i2++] = (rest < 10) ? char(rest) + '0' : char(rest) - 10 + 'A';
}
while(value != 0 && i2 < buf_len);
if( i2 >= buf_len )
{
buffer[0] = 0; // ops, the buffer was too small
return false;
}
buffer[i2--] = 0;
for( ; i1 < i2 ; ++i1, --i2)
{
CharType temp = buffer[i1];
buffer[i1] = buffer[i2];
buffer[i2] = temp;
}
return true;
}
// if the buffer is too small it will be terminated at the beginning (empty string)
// and the function returns false
template<class CharType>
bool Toa(long value, CharType * buffer, size_t buf_len, int base = 10)
{
if( buf_len == 0 )
return false;
CharType * buf = buffer;
if( value < 0 )
{
buffer[0] = '-';
buf += 1;
buf_len -= 1;
value = -value;
}
bool res = Toa(static_cast<unsigned long>(value), buf, buf_len, base);
if( !res )
buffer[0] = 0;
return res;
}
template<class CharType>
bool Toa(unsigned int value, CharType * buffer, size_t buf_len, int base = 10)
{
return Toa(static_cast<unsigned long>(value), buffer, buf_len, base);
}
template<class CharType>
bool Toa(int value, CharType * buffer, size_t buf_len, int base = 10)
{
return Toa(static_cast<long>(value), buffer, buf_len, base);
}
// warning: it uses its own static buffer
// one buffer for both these functions
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);
/*
conversions between ascii text and wide characters
(destination is always std::string or std::wstring)
characters are copied as they are without any locales checking
*/
void AssignString(const char * src, size_t len, std::wstring & dst, bool clear = true);
void AssignString(const char * src, std::wstring & dst, bool clear = true);
void AssignString(const std::string & src, std::wstring & dst, bool clear = true);
void AssignString(const wchar_t * src, size_t len, std::string & dst, bool clear = true);
void AssignString(const wchar_t * src, std::string & dst, bool clear = true);
void AssignString(const std::wstring & src, std::string & dst, bool clear = true);
void AssignString(const char * src, size_t len, std::string & dst, bool clear = true);
void AssignString(const char * src, std::string & dst, bool clear = true);
void AssignString(const std::string & src, std::string & dst, bool clear = true);
void AssignString(const wchar_t * src, size_t len, std::wstring & dst, bool clear = true);
void AssignString(const wchar_t * src, std::wstring & dst, bool clear = true);
void AssignString(const std::wstring & src, std::wstring & dst, bool clear = true);
bool CorrectUrlChar(wchar_t c);
void CorrectUrlDots(std::wstring & url);
void CorrectUrlChars(std::wstring & url);
void CorrectUrlOnlyAllowedChar(std::wstring & url);
const wchar_t * DateToStr(int year, int month, int day);
const wchar_t * DateToStr(int year, int month, int day, int hour, int min, int sec);
const wchar_t * DateToStr(const tm * ptm);
const wchar_t * DateToStr(const tm & rtm);
const wchar_t * DateToStr(time_t t);
const wchar_t * DateToStrWithoutHours(const tm * ptm);
const wchar_t * DateToStrWithoutHours(const tm & rtm);
const wchar_t * DateToStrWithoutHours(time_t t);
const char * DateToStrCookie(int year, int month, int day, int hour, int min, int sec);
const char * DateToStrCookie(tm * ptm);
const char * DateToStrCookie(const tm * ptm);
const char * DateToStrCookie(const tm & rtm);
const char * DateToStrCookie(time_t t);
const char * IpToStr(unsigned int ip_);
const wchar_t * IpToStr(unsigned int ip_);
bool IsWhite(wchar_t s);
template<class StringType>
void TrimWhite(StringType & s)
{
typename StringType::size_type i;
if( s.empty() )
return;
// looking for white characters at the end
for(i=s.size()-1 ; i>0 && IsWhite(s[i]) ; --i);
if( i==0 && IsWhite(s[i]) )
{
// the whole string has white characters
s.clear();
return;
}
// deleting white characters at the end
if( i != s.size() - 1 )
s.erase(i+1, StringType::npos);
// looking for white characters at the beginning
for(i=0 ; i<s.size() && IsWhite(s[i]) ; ++i);
// deleting white characters at the beginning
if( i != 0 )
s.erase(0, i);
}
template<class StringType>
void Trim(StringType & s, wchar_t c)
{
typename StringType::size_type i;
if( s.empty() )
return;
// looking for the 'c' characters at the end
for(i=s.size()-1 ; i>0 && s[i]==c ; --i);
if( i==0 && s[i]==c )
{
// the whole string has the 'c' characters
s.clear();
return;
}
// deleting 'c' characters at the end
if( i != s.size() - 1 )
s.erase(i+1, StringType::npos);
// looking for the 'c' characters at the beginning
for(i=0 ; i<s.size() && s[i]==c ; ++i);
// deleting the 'c' characters at the beginning
if( i != 0 )
s.erase(0, i);
}
wchar_t ToSmall(wchar_t c);
void ToSmall(std::wstring & s);
bool IsWhite(int s);
void TrimWhite(std::string & s);
void Trim(std::string & s, char c);
int ToSmall(int c);
void ToSmall(std::string & s);
const char * SkipWhite(const char * s);
const char * ToStr(int value);
const wchar_t * SkipWhite(const wchar_t * s);
bool IsSubString(const char * short_str, const char * long_str);
bool IsSubStringNoCase(const char * short_str, const char * long_str);
bool EqualNoCase(const char * str1, const char * str2);
bool ValidateEmail(const std::string & email);
bool IsFile(const char * file);
bool IsFile(const std::string & file);
bool CreateDir(const char * dir, int priv);
bool CreateDir(const std::string & dir, int priv);
bool CreateDirs(const char * base_dir, const char * dirs, int priv);
bool CreateDirs(const std::string & base_dir, const std::string & dirs, int priv);
template<class StringType1, class StringType2>
bool IsSubString(const StringType1 * short_str, const StringType2 * long_str)
{
while( *short_str && *long_str && wchar_t(*short_str) == wchar_t(*long_str) )
{
++short_str;
++long_str;
}
if( *short_str == 0 )
return true;
return false;
}
template<class StringType1, class StringType2>
bool IsSubString(const StringType1 & short_str, const StringType2 & long_str)
{
return IsSubString(short_str.c_str(), long_str.c_str());
}
template<class StringType1, class StringType2>
bool IsSubStringNoCase(const StringType1 * short_str, const StringType2 * long_str)
{
while( *short_str && *long_str && ToSmall(*short_str) == ToSmall(*long_str) )
{
++short_str;
++long_str;
}
if( *short_str == 0 )
return true;
return false;
}
template<class StringType1, class StringType2>
bool IsSubStringNoCase(const StringType1 & short_str, const StringType2 & long_str)
{
return IsSubStringNoCase(short_str.c_str(), long_str.c_str());
}
template<class StringType1, class StringType2>
bool Equal(const StringType1 * str1, const StringType2 * str2)
{
while( *str1 && *str2 && wchar_t(*str1) == wchar_t(*str2) )
{
++str1;
++str2;
}
if( *str1 == 0 && *str2 == 0 )
return true;
return false;
}
template<class StringType1, class StringType2>
bool Equal(const StringType1 & str1, const StringType2 & str2)
{
return Equal(str1.c_str(), str2.c_str());
}
template<class StringType1, class StringType2>
bool EqualNoCase(const StringType1 * str1, const StringType2 * str2)
{
while( *str1 && *str2 && ToSmall(*str1) == ToSmall(*str2) )
{
++str1;
++str2;
}
if( *str1 == 0 && *str2 == 0 )
return true;
return false;
}
template<class StringType1, class StringType2>
bool EqualNoCase(const StringType1 & str1, const StringType2 & str2)
{
return EqualNoCase(str1.c_str(), str2.c_str());
}
template<class StringType>
void NoLastSlash(StringType & s)
{
if( s.empty() )
return;
size_t i = s.size();
for( ; i>0 && s[i-1]=='/' ; --i);
if( i < s.size() )
s.erase(i);
}
template<class StringType>
void NoFirstHttp(StringType & s)
{
if( s.empty() )
return;
const char http[] = "http://";
const char https[] = "https://";
if( IsSubStringNoCase(http, s.c_str()) )
{
s.erase(0, sizeof(http)/sizeof(char));
}
else
if( IsSubStringNoCase(https, s.c_str()) )
{
s.erase(0, sizeof(https)/sizeof(char));
}
}
bool ValidateEmail(const std::wstring & email);
bool IsFile(const wchar_t * file);
bool IsFile(const std::wstring & file);
bool CreateDir(const wchar_t * dir, int priv);
bool CreateDir(const std::wstring & dir, int priv);
// creating directories (dirs) under base_dir (base_dir must exist)
// if skip_last == true then last part from dir is treated as a file (the last directory is not created)
bool CreateDirs(const wchar_t * base_dir, const wchar_t * dirs, int priv = 0755, bool skip_last = false);
bool CreateDirs(const std::wstring & base_dir, const std::wstring & dirs, int priv = 0755, bool skip_last = false);
bool CopyFile(FILE * in, FILE * out);
bool CopyFile(const char * src, const char * dst);
bool CopyFile(const std::string & src, const std::string & dst);
bool CopyFile(const wchar_t * src, const wchar_t * dst);
bool CopyFile(const std::wstring & src, const std::wstring & dst);
bool RemoveFile(const wchar_t * file);
bool RemoveFile(const std::wstring & file);
bool RenameFile(const wchar_t * from, const wchar_t * to);
bool RenameFile(const std::wstring & from, const std::wstring & to);
const wchar_t * GetFileExt(const wchar_t * name);
int SelectFileType(const wchar_t * file_name);
int SelectFileType(const std::wstring & file_name);
time_t Time(const tm & par);
time_t Time(const tm * par);
tm Time(time_t par);
void UrlEncode(const std::string & in, std::string & out, bool clear_out = true);
void UrlEncode(const std::wstring & in, std::string & out, bool clear_out = true);
const char * GetFileExt(const char * name);
Item::Auth SelectFileType(const char * file_name);
#endif

View File

@@ -2,118 +2,21 @@
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2009, Tomasz Sowa
* Copyright (c) 2009-2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "mount.h"
#include "misc.h"
Mount::Mount()
{
type = cms;
dir_id = -1;
fs = simplefs;
param.resize(par_none);
}
const char * Mount::TypeToStr()
{
static char buffer[30];
switch( type )
{
case cms:
sprintf(buffer, "cms");
break;
case thread:
sprintf(buffer, "thread");
break;
case ticket:
sprintf(buffer, "ticket");
break;
default:
sprintf(buffer, "unknown");
break;
}
return buffer;
}
const char * Mount::FsToStr()
{
static char buffer[30];
switch( fs )
{
case simplefs:
sprintf(buffer, "simplefs");
break;
case hashfs:
sprintf(buffer, "hashfs");
break;
default:
sprintf(buffer, "unknown");
break;
}
return buffer;
}
Mount::ParamCode Mount::ParseParam(const char * param_name)
{
struct ParName
{
ParamCode param_code;
const char * name;
};
static ParName par_name_tab[] = {
{ par_page, "page" },
{ par_thread, "thread" },
{ par_ticket, "ticket" },
{ par_ticket_type, "ticket_type" },
{ par_ticket_type_default, "ticket_type_default" },
{ par_ticket_status, "ticket_status" },
{ par_ticket_status_default, "ticket_status_default" },
{ par_ticket_priority, "ticket_priority" },
{ par_ticket_priority_default, "ticket_priority_default" },
{ par_ticket_category, "ticket_category" },
{ par_ticket_category_default, "ticket_category_default" },
{ par_ticket_expected, "ticket_expected" },
{ par_ticket_expected_default, "ticket_expected_default" },
{ par_createthread_on, "createthread_on" },
{ par_createticket_on, "createticket_on" },
{ par_only_root_remove, "only_root_remove" },
{ par_emacs_on, "emacs_on" },
{ par_mkdir_on, "mkdir_on" },
{ par_app, "app" },
{ par_html_template, "html_template" },
};
size_t i, len = sizeof(par_name_tab) / sizeof(ParName);
for(i=0 ; i<len ; ++i)
{
if( strcmp(par_name_tab[i].name, param_name) == 0 )
return par_name_tab[i].param_code;
}
return par_none;
type = -1;
fs = -1;
}
@@ -127,8 +30,11 @@ size_t i;
}
bool Mount::IsPar(Mount::ParamCode code)
bool Mount::IsPar(int code)
{
if( code < 0 || code >= (int)param.size() )
return false;
if( !param[code].defined )
return false;
@@ -137,9 +43,12 @@ return true;
bool Mount::IsArg(Mount::ParamCode code, const char * arg)
bool Mount::IsArg(int code, const wchar_t * arg)
{
ParamArg::iterator i;
ParamRow::ParamArg::iterator i;
if( code < 0 || code >= (int)param.size() )
return false;
if( !param[code].defined )
return false;
@@ -154,22 +63,25 @@ return false;
}
bool Mount::IsArg(Mount::ParamCode code, const std::string & arg)
bool Mount::IsArg(int code, const std::wstring & arg)
{
return IsArg(code, arg.c_str());
}
bool Mount::IsArg(Mount::ParamCode code, int arg)
bool Mount::IsArg(int code, int arg)
{
ParamArg::iterator i;
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( atoi(i->c_str()) == arg )
if( Toi(*i) == arg )
return true;
}
@@ -177,15 +89,23 @@ return false;
}
const std::string * Mount::HtmlTemplate() const
const std::wstring & Mount::Arg(int code, int arg) const
{
if( !param[par_html_template].defined )
return 0;
if( code < 0 || code >= (int)param.size() )
return empty_str;
if( param[par_html_template].arg.size() != 1 )
return 0;
if( !param[code].defined )
return empty_str;
return & param[par_html_template].arg[0];
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);
}

View File

@@ -2,7 +2,7 @@
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2009, Tomasz Sowa
* Copyright (c) 2009-2010, Tomasz Sowa
* All rights reserved.
*
*/
@@ -17,59 +17,14 @@
class Mount
{
public:
enum Type
{
cms = 0,
thread,
ticket
};
enum Fs
{
simplefs = 0,
hashfs
};
// the first should be with 0 index
// the last should be 'none'
enum ParamCode
{
par_page = 0,
par_thread,
par_ticket,
par_ticket_type,
par_ticket_type_default,
par_ticket_status,
par_ticket_status_default,
par_ticket_priority,
par_ticket_priority_default,
par_ticket_category,
par_ticket_category_default,
par_ticket_expected,
par_ticket_expected_default,
par_createthread_on,
par_createticket_on,
par_only_root_remove,
par_emacs_on,
par_mkdir_on,
par_app,
par_html_template,
par_none
};
typedef std::vector<std::string> ParamArg;
struct ParamRow
{
typedef std::vector<std::wstring> ParamArg;
bool defined;
ParamArg arg;
@@ -78,31 +33,36 @@ public:
};
typedef std::vector<ParamRow> Param;
long dir_id;
int type;
int fs;
Param param;
long dir_id;
Type type;
Fs fs;
Mount();
const char * TypeToStr();
const char * FsToStr();
static ParamCode ParseParam(const char * param);
void ClearParams();
bool IsPar(int code);
bool IsPar(Mount::ParamCode code);
bool IsArg(int code, const wchar_t * arg);
bool IsArg(int code, const std::wstring & arg);
bool IsArg(int code, int arg);
bool IsArg(Mount::ParamCode code, const char * arg);
bool IsArg(Mount::ParamCode code, const std::string & arg);
bool IsArg(Mount::ParamCode code, int arg);
// returning the arg argument if defined (or an empty string)
const std::wstring & Arg(int code, int arg) const;
// returning a name to html template (can be null if not defined)
const std::string * HtmlTemplate() 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;
};

View File

@@ -12,12 +12,40 @@
#include "misc.h"
MountParser::MountParser()
{
dirs = 0;
mount_type_tab = 0;
mount_fs_tab = 0;
mount_par_tab = 0;
}
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 )
@@ -44,7 +72,7 @@ void MountParser::SkipLine()
}
void MountParser::ReadWordQuote(std::string & res)
void MountParser::ReadWordQuote(std::wstring & res)
{
++pinput;
@@ -74,7 +102,7 @@ void MountParser::ReadWordQuote(std::string & res)
// a white character is the separator
void MountParser::ReadWordWhite(std::string & res)
void MountParser::ReadWordWhite(std::wstring & res)
{
while( *pinput && *pinput!=10 && !IsWhite(*pinput) )
{
@@ -85,7 +113,7 @@ void MountParser::ReadWordWhite(std::string & res)
// the comma or the second bracket ')' are the separators
void MountParser::ReadWordComma(std::string & res)
void MountParser::ReadWordComma(std::wstring & res)
{
while( *pinput && *pinput!=10 && *pinput!=',' && *pinput!=')' )
{
@@ -99,7 +127,7 @@ void MountParser::ReadWordComma(std::string & res)
}
void MountParser::ReadWord(std::string & res, bool comma_bracket_separator)
void MountParser::ReadWord(std::wstring & res, bool comma_bracket_separator)
{
res.clear();
SkipWhite();
@@ -122,7 +150,7 @@ void MountParser::ReadWord(std::string & res, bool comma_bracket_separator)
void MountParser::ReadParamArgsLoop(Mount::ParamArg & args)
void MountParser::ReadParamArgsLoop(Mount::ParamRow::ParamArg & args)
{
SkipWhite();
@@ -139,7 +167,7 @@ void MountParser::ReadParamArgsLoop(Mount::ParamArg & args)
}
void MountParser::ReadParamArgs(Mount::ParamArg & args)
void MountParser::ReadParamArgs(Mount::ParamRow::ParamArg & args)
{
SkipWhite();
args.clear();
@@ -164,7 +192,7 @@ void MountParser::ReadParamArgs(Mount::ParamArg & args)
void MountParser::ReadParamName(std::string & res)
void MountParser::ReadParamName(std::wstring & res)
{
SkipWhite();
res.clear();
@@ -177,7 +205,7 @@ void MountParser::ReadParamName(std::string & res)
}
void MountParser::ReadParam(std::string & res, Mount::ParamArg & args)
void MountParser::ReadParam(std::wstring & res, Mount::ParamRow::ParamArg & args)
{
ReadParamName(res);
@@ -193,6 +221,17 @@ void MountParser::ReadParam(std::string & res, Mount::ParamArg & args)
}
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;
}
void MountParser::ReadMountType()
{
@@ -202,24 +241,14 @@ void MountParser::ReadMountType()
{
// an empty line (some white characters only)
err = WINIX_ERR_EMPTY;
return;
}
else
if( temp == "cms" )
mount.type = FindIndex(mount_type_tab, temp);
if( mount.type != -1 )
{
mount.type = Mount::cms;
log << log3 << "MP: mount type: cms" << logend;
}
else
if( temp == "thread" )
{
mount.type = Mount::thread;
log << log3 << "MP: mount type: thread" << logend;
}
else
if( temp == "ticket" )
{
mount.type = Mount::ticket;
log << log3 << "MP: mount type: ticket" << logend;
log << log3 << "MP: mount type: " << (*mount_type_tab)[mount.type] << logend;
}
else
{
@@ -239,12 +268,12 @@ void MountParser::ReadMountPoint()
if( pdir )
{
mount.dir_id = pdir->id;
log << log3 << "MP: mount point: " << temp << logend;
log << log3 << "MP: mount point (directory): " << temp << logend;
}
else
{
err = WINIX_ERR_NO_MOUNTPOINT;
log << log1 << "MP: there is no such a mount point: " << temp << logend;
log << log1 << "MP: there is no such a mount point (directory): " << temp << logend;
}
}
@@ -253,17 +282,11 @@ void MountParser::ReadMountPoint()
void MountParser::ReadFs()
{
ReadWord(temp);
mount.fs = FindIndex(mount_fs_tab, temp);
if( temp == "simplefs" )
if( mount.fs != -1 )
{
mount.fs = Mount::simplefs;
log << log1 << "MP: file system: simplefs" << logend;
}
else
if( temp == "hashfs" )
{
mount.fs = Mount::hashfs;
log << log1 << "MP: file system: hashfs" << logend;
log << log2 << "MP: file system: " << (*mount_fs_tab)[mount.fs] << logend;
}
else
{
@@ -299,12 +322,12 @@ void MountParser::ReadMountParams()
for( ReadParam(temp, param_args) ; !temp.empty() ; ReadParam(temp, param_args) )
{
Mount::ParamCode p = Mount::ParseParam(temp.c_str());
int code = FindIndex(mount_par_tab, temp);
if( p != Mount::par_none )
if( code != -1 )
{
mount.param[p].defined = true;
mount.param[p].arg = param_args;
mount.param[code].defined = true;
mount.param[code].arg = param_args;
LogMountParams();
}
else
@@ -350,15 +373,30 @@ void MountParser::ReadRow(std::map<long, Mount> & output)
Error MountParser::Parse(const std::string & input, std::map<long, Mount> & output)
Error MountParser::Parse(const std::wstring & input, std::map<long, Mount> & output)
{
if( !dirs || !mount_type_tab || !mount_fs_tab || !mount_par_tab )
{
log << log1 << "pdir: " << pdir << logend;
log << log1 << "type: " << mount_type_tab << logend;
log << log1 << "fs: " << mount_fs_tab << logend;
log << log1 << "par: " << mount_par_tab << logend;
log << log1 << "MP: input tables not set" << logend;
return WINIX_NOTHING_TO_DO; // !! may a better code?
}
pinput = input.c_str();
err = WINIX_ERR_OK;
mount.param.resize(mount_par_tab->size());
mount.ClearParams();
output.clear();
while( *pinput && err == WINIX_ERR_OK )
ReadRow(output);
return err;
}

View File

@@ -27,24 +27,33 @@ class MountParser
{
public:
Error Parse(const std::string & input, std::map<long, Mount> & output);
MountParser();
Error 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;
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::string & res);
void ReadWordWhite(std::string & res);
void ReadWordComma(std::string & res);
void ReadWord(std::string & res, bool comma_bracket_separator = false);
void ReadParamArgsLoop(Mount::ParamArg & args);
void ReadParamArgs(Mount::ParamArg & args);
void ReadParamName(std::string & res);
void ReadParam(std::string & res, Mount::ParamArg & args);
void 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);
void ReadMountType();
void ReadMountPoint();
void ReadFs();
@@ -52,10 +61,10 @@ private:
void ReadMountParams();
void ReadRow(std::map<long, Mount> & output);
const char * pinput;
std::string temp;
std::string temp_arg;
Mount::ParamArg param_args;
const wchar_t * pinput;
std::wstring temp;
std::wstring temp_arg;
Mount::ParamRow::ParamArg param_args;
Mount mount;

View File

@@ -2,7 +2,7 @@
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2009, Tomasz Sowa
* Copyright (c) 2009-2010, Tomasz Sowa
* All rights reserved.
*
*/
@@ -10,8 +10,8 @@
#include "mounts.h"
#include "request.h"
#include "log.h"
#include "mountparser.h"
#include "db.h"
#include "db/db.h"
#include "plugin.h"
@@ -22,6 +22,44 @@ Mounts::Mounts()
}
void Mounts::CreateMountType()
{
mount_type_cms = AddMountType(L"cms");
mount_type_thread = AddMountType(L"thread");
}
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_thread = AddMountPar(L"thread");
mount_par_createthread_on = AddMountPar(L"createthread_on");
mount_par_only_root_remove = AddMountPar(L"only_root_remove");
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");
}
void Mounts::CreateMounts()
{
CreateMountType();
CreateMountFs();
CreateMountPar();
plugin.Call(WINIX_ADD_MOUNTS);
}
void Mounts::SetDirs(Dirs * pdirs)
{
dirs = pdirs;
@@ -40,12 +78,97 @@ void Mounts::SetRequest(Request * prequest)
// reading from 'mounts'
Error Mounts::ReadMounts(const std::string & mounts)
int Mounts::AddMountType(const wchar_t * type)
{
MountParser mp;
mp.SetDirs(dirs);
Error err = mp.Parse(mounts, mount_tab);
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'
Error Mounts::ReadMounts(const std::wstring & mounts)
{
mount_parser.SetDirs(dirs);
mount_parser.SetMountTypeTab(mount_type_tab);
mount_parser.SetMountFsTab(mount_fs_tab);
mount_parser.SetMountParTab(mount_par_tab);
Error err = mount_parser.Parse(mounts, mount_tab);
if( err != WINIX_ERR_OK )
{
@@ -54,6 +177,7 @@ Error Mounts::ReadMounts(const std::string & mounts)
}
CalcCurMount();
plugin.Call(WINIX_FSTAB_CHANGED);
return err;
}
@@ -63,7 +187,7 @@ return err;
// reading from /etc/fstab
Error Mounts::ReadMounts()
{
static std::string file = "fstab";
static std::wstring file = L"fstab";
Item * etc = dirs->GetEtcDir();
@@ -95,8 +219,8 @@ Error Mounts::ReadMounts()
void Mounts::MountCmsForRoot()
{
Mount mount;
mount.type = Mount::cms;
mount.fs = Mount::simplefs;
mount.type = MountTypeCms();
mount.fs = MountFsSimplefs();
Item * proot = dirs->GetRootDir();
@@ -108,6 +232,9 @@ void Mounts::MountCmsForRoot()
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);
}
@@ -119,20 +246,20 @@ void Mounts::CalcCurMount()
{
std::vector<Item*>::reverse_iterator i;
// when the program starts (when the dir_table is empty()
// when the program starts (when the dir_tab is empty()
// we don't want to call MountCmsForRoot()
if( request->dir_table.empty() )
if( request->dir_tab.empty() )
return;
for(i = request->dir_table.rbegin() ; i!=request->dir_table.rend() ; ++i)
for(i = request->dir_tab.rbegin() ; i!=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: " << pmount->TypeToStr()
<< ", fs: " << pmount->FsToStr() << logend;
log << log2 << "M: current mount point is: " << GetMountType(pmount->type)
<< ", fs: " << GetMountFs(pmount->fs) << logend;
return;
}
}
@@ -140,8 +267,8 @@ std::vector<Item*>::reverse_iterator i;
// if nothing was found
// we assume that 'cms' mount point is used
MountCmsForRoot();
log << log2 << "M: current mount point is: " << pmount->TypeToStr() << " (default)"
<< ", fs: " << pmount->FsToStr() << logend;
log << log2 << "M: current mount point is: " << GetMountType(pmount->type) << " (default)"
<< ", fs: " << GetMountFs(pmount->fs) << logend;
}

View File

@@ -2,7 +2,7 @@
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2009, Tomasz Sowa
* Copyright (c) 2009-2010, Tomasz Sowa
* All rights reserved.
*
*/
@@ -14,11 +14,13 @@
#include <map>
#include <string>
#include <vector>
#include "mount.h"
#include "error.h"
#include "dirs.h"
#include "db.h"
#include "db/db.h"
#include "request.h"
#include "mountparser.h"
@@ -26,6 +28,51 @@ class Mounts
{
public:
/*
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 MountTypeThread() { return mount_type_thread; }
// 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 MountParThread() { return mount_par_thread; }
int MountParCreatethreadOn() { return mount_par_createthread_on; }
int MountParOnlyRootRemove() { return mount_par_only_root_remove; }
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; }
void SetDirs(Dirs * pdirs);
void SetDb(Db * pdb);
void SetRequest(Request * prequest);
@@ -34,7 +81,9 @@ public:
typedef std::map<long, Mount> MountTab;
Mounts();
Error ReadMounts(const std::string & mounts);
void CreateMounts();
Error ReadMounts(const std::wstring & mounts);
Error ReadMounts();
void CalcCurMount();
@@ -49,12 +98,48 @@ public:
private:
Dirs * dirs;
Db * db;
Dirs * dirs;
Request * request;
const std::wstring empty_str;
MountParser mount_parser;
// cms
// thread
std::vector<std::wstring> mount_type_tab;
int mount_type_cms;
int mount_type_thread;
// simplefs
// hashfs
std::vector<std::wstring> mount_fs_tab;
int mount_fs_simplefs;
int mount_fs_hashfs;
// page
// thread
std::vector<std::wstring> mount_par_tab;
int mount_par_page;
int mount_par_thread;
int mount_par_createthread_on;
int mount_par_only_root_remove;
int mount_par_emacs_on;
int mount_par_mkdir_on;
int mount_par_app;
int mount_par_html_template;
MountTab mount_tab;
void CreateMountType();
void CreateMountFs();
void CreateMountPar();
void MountCmsForRoot();
};

View File

@@ -1,288 +0,0 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#include <pthread.h>
#include <unistd.h>
#include "log.h"
#include "notify.h"
#include "misc.h"
#include "request.h"
// the second thread uses this pointer to reference to 'this'
// (methods for the thread should be static)
Notify * Notify::obj;
void Notify::SetRequest(Request * prequest)
{
request = prequest;
}
void Notify::SetConfig(Config * pconfig)
{
config = pconfig;
}
void Notify::SetSystem(System * psystem)
{
system = psystem;
}
void Notify::SetTemplatesNotify(TemplatesNotify * ptemplates_notify)
{
templates_notify = ptemplates_notify;
}
/*
methods for the second thread
the thread can reference to 'this' by using 'obj' pointer
*/
void * Notify::ThreadRoutine(void * arg)
{
obj = (Notify*)arg;
while( true )
{
CheckQueue();
sleep(30);
}
}
void Notify::CheckQueue()
{
std::list<NotifyMsg>::iterator i = obj->notify_pool.begin();
while( i != obj->notify_pool.end() )
{
SendEmail(*i);
obj->Lock();
i = obj->notify_pool.erase(i);
obj->Unlock();
sleep(3);
}
}
void Notify::SendEmail(NotifyMsg & n)
{
TemplatesNotifyFunctions::notify_msg = &n;
obj->Lock(); // templates can be reloaded from the first thread
obj->templates_notify->Generate(n.lang);
obj->Unlock();
SendEmail(n.email, obj->templates_notify->notify_str.str());
}
void Notify::SendEmail(const std::string & email, const std::string & message)
{
nlog.PutDate(log1);
if( !ValidateEmail(email) )
{
nlog << "Notify: email: " << email << " is not correct" << logend;
return;
}
obj->command = "sendmail " + email;
FILE * sendmail = popen(obj->command.c_str(), "w");
if( !sendmail )
{
nlog << "Notify: can't run sendmail" << logend;
return;
}
SendMessage(sendmail, message);
pclose(sendmail);
nlog << "Notify: email to: " << email << " has been sent" << logend;
nlog << logsave;
}
void Notify::SendMessage(FILE * sendmail, const std::string & message)
{
for(size_t i=0 ; i<message.length() ; ++i)
{
if( message[i] == '\n' )
fprintf(sendmail, "\r\n");
else
fputc(message[i], sendmail);
}
}
/*
methods for main thread
*/
Notify::Notify() : mutex(PTHREAD_MUTEX_INITIALIZER)
{
}
Notify::~Notify()
{
}
void Notify::ReadTemplates()
{
// we are in the first thread here
// the second thread can use our templates and we must Lock()
// (the second thread is using Lock() too)
Lock();
templates_notify->Read();
Unlock();
}
bool Notify::Init()
{
templates_notify->CreateFunctions();
int t = pthread_create(&thread, 0, ThreadRoutine, (void*)this);
if( t != 0 )
{
// log (not nlog) here
log << log1 << "Notify: can't create a thread" << logend;
return false;
}
return true;
}
bool Notify::Lock()
{
if( pthread_mutex_lock(&mutex) != 0 )
return false;
return true;
}
void Notify::Unlock()
{
pthread_mutex_unlock(&mutex);
}
void Notify::CreateItemDir(std::string & dir, bool clear)
{
if( clear )
dir.clear();
for(size_t a=0 ; a<request->dir_table.size() ; ++a)
{
dir += request->dir_table[a]->url;
dir += '/';
}
}
void Notify::CreateItemLink(std::string & link)
{
link = config->base_url;
CreateItemDir(link, false);
link += request->item.url;
}
void Notify::ItemChanged(int notify_code)
{
bool sending;
Users::Iterator i;
if( notify_code == 0 )
return;
n.notify_code = notify_code;
n.current_mount_type = system->mounts.pmount->type;
n.doc_base_url = config->base_url;
CreateItemDir(n.item_dir);
CreateItemLink(n.item_link);
Lock();
try
{
// don't clear notify_pool here -- it is used (and will be cleared) by the second thread
for(i=system->users.Begin() ; i != system->users.End() ; ++i)
{
sending = false;
if( system->mounts.pmount->type == Mount::thread )
{
if( (i->thread_notify & notify_code) != 0 )
sending = true;
}
else
if( system->mounts.pmount->type == Mount::cms )
{
if( (i->cms_notify & notify_code) != 0 )
sending = true;
}
if( sending )
{
n.email = i->email;
n.lang = Locale::StrToLang(config->locale_str);// !! bedzie osobno dla kazdego uzytkownika
if( n.lang == Locale::lang_unknown )
n.lang = Locale::lang_en;
notify_pool.insert(notify_pool.end(), n);
}
}
}
catch(...)
{
Unlock();
throw;
}
Unlock();
}

View File

@@ -1,91 +0,0 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilecmslunotify
#define headerfilecmslunotify
#include <list>
#include <string>
#include <cstdio>
#include "templatesnotify/templatesnotify.h"
#include "request.h"
#include "config.h"
#include "system.h"
#include "users.h"
#define WINIX_NOTIFY_ITEM_ADD 1
#define WINIX_NOTIFY_ITEM_EDIT 2
#define WINIX_NOTIFY_ITEM_DELETE 4
#define WINIX_NOTIFY_DIR_ADD 8
class Notify
{
public:
Notify();
~Notify();
void SetRequest(Request * prequest);
void SetConfig(Config * pconfig);
void SetSystem(System * psystem);
void SetTemplatesNotify(TemplatesNotify * ptemplates_notify);
void ReadTemplates();
bool Init();
/*
this method addes an item to our special pool
the pool is used by a second thread
*/
void ItemChanged(int notify_code);
private:
Request * request;
Config * config;
System * system;
TemplatesNotify * templates_notify;
static void * ThreadRoutine(void * arg);
bool Lock();
void Unlock();
static void CheckQueue();
static void SendEmail(NotifyMsg & n);
static void SendEmail(const std::string & email);
static void SendEmail(const std::string & email, const std::string & message);
static void SendMessage(FILE * sendmail, const std::string & message);
void CreateItemDir(std::string & dir, bool clear = true);
void CreateItemLink(std::string & link);
pthread_t thread;
pthread_mutex_t mutex;
NotifyMsg n;
/*
objects accessed by the second thread
*/
std::list<NotifyMsg> notify_pool;
static Notify * obj;
std::string command;
};
#endif

View File

@@ -8,8 +8,10 @@
*/
#include <dlfcn.h>
#include <string.h>
#include "plugin.h"
#include "pluginmsg.h"
#include "misc.h"
@@ -30,7 +32,7 @@ size_t i;
Plugin::Plugin()
{
current_plugin = -1;
request = 0;
request = 0;
db = 0;
config = 0;
@@ -38,6 +40,7 @@ Plugin::Plugin()
system = 0;
functions = 0;
templates = 0;
synchro = 0;
session_manager = 0;
}
@@ -83,16 +86,24 @@ void Plugin::SetTemplates(Templates * ptemplates)
}
void Plugin::SetSynchro(Synchro * psynchro)
{
synchro = psynchro;
}
void Plugin::SetSessionManager(SessionManager * psession_manager)
{
session_manager = psession_manager;
}
bool Plugin::SetPointers(PluginInfo & info)
{
// for safety we call a plugin function only when all our pointers are not null
bool res = (db && config && request && system && functions && templates && session_manager);
bool res = (db && config && request && system && functions && templates && synchro && session_manager);
if( !res )
log << log1 << "Plugin: cannot call a function - some of the winix pointers are null" << logend;
@@ -103,18 +114,29 @@ bool Plugin::SetPointers(PluginInfo & info)
info.system = system;
info.functions = functions;
info.templates = templates;
info.synchro = synchro;
info.session_manager = session_manager;
return res;
}
void Plugin::LoadPlugins(const std::vector<std::string> & plugins)
void Plugin::LoadPlugins(const std::wstring & plugins_dir, const std::vector<std::wstring> & plugins)
{
size_t i;
for(i=0 ; i<plugins.size() ; ++i)
LoadPlugin(plugins[i]);
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);
}
}
}
@@ -146,7 +168,7 @@ void * Plugin::LoadInitFun(const char * filename, Fun1 & fun_init)
return 0;
}
log << log1 << "Plugin: plugin loaded"
log << log2 << "Plugin: plugin loaded"
<< ", file: " << filename
<< ", index: " << plugins.size() << logend;
@@ -176,7 +198,7 @@ int old_current_plugin;
PluginsItem item;
item.handle = plugin_handle;
item.plugin_name = reinterpret_cast<const char *>(info.p1);
item.plugin_name = reinterpret_cast<const wchar_t *>(info.p1);
plugins.push_back(item);
@@ -184,6 +206,41 @@ int 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());
}
void Plugin::Call(int message, Slots::iterator & slot)
{
@@ -200,6 +257,9 @@ void Plugin::Call(int message, Slots::iterator & slot)
if( !slot->second.is_running )
{
if( config->log_plugin_call )
log << log1 << "Plugin: calling plugin id: " << slot->second.index << ", message: " << message << logend;
slot->second.is_running = true;
if( slot->second.fun1 )
@@ -209,6 +269,10 @@ void Plugin::Call(int message, Slots::iterator & slot)
slot->second.fun2();
slot->second.is_running = false;
if( config->log_plugin_call )
log << log1 << "Plugin: returning from plugin id: " << slot->second.index << ", message: " << message << logend;
}
else
{
@@ -301,6 +365,9 @@ void Plugin::Assign(int message, Fun1 fun1)
{
Slot s;
if( current_plugin == -1 )
return;
s.fun1 = fun1;
s.index = current_plugin;
@@ -313,6 +380,9 @@ void Plugin::Assign(int message, Fun2 fun2)
{
Slot s;
if( current_plugin == -1 )
return;
s.fun2 = fun2;
s.index = current_plugin;

View File

@@ -21,6 +21,7 @@
#include "request.h"
#include "system.h"
#include "sessionmanager.h"
#include "synchro.h"
#include "functions/functions.h"
#include "templates/templates.h"
@@ -63,6 +64,7 @@ struct PluginInfo
System * system;
Functions * functions;
Templates * templates;
Synchro * synchro;
SessionManager * session_manager;
// pointer to the plugin session (can be null if not set by the plugin)
@@ -132,13 +134,20 @@ public:
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 LoadPlugins(const std::vector<std::string> & plugins);
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);
void Call(int message);
void Call(int message, void * p1_);
void Call(int message, void * p1_, void * p2_);
@@ -165,13 +174,15 @@ private:
System * system;
Functions * functions;
Templates * templates;
Synchro * synchro;
SessionManager * session_manager;
std::wstring temp_path;
struct PluginsItem
{
void * handle;
const char * plugin_name; // plugin name (can be null if was not set by the plugin)
const wchar_t * plugin_name; // plugin name (can be null if was not set by the plugin)
};
typedef std::vector<PluginsItem> Plugins;
@@ -182,6 +193,8 @@ private:
PluginInfo info;
std::string afilename;
void * LoadInitFun(const char * filename, Fun1 & fun_init);
void Call(int message, Slots::iterator & slot);

View File

@@ -15,10 +15,32 @@
// PluginInfo.p1 is a pointer to Ezc::Functions object
#define WINIX_TEMPLATES_CREATEFUNCTIONS 999
#define WINIX_REQUEST_CLEAR 1000
// 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;
#define WINIX_NOTIFY_TEMPLATES_CREATEFUNCTIONS 998
#define WINIX_CONTENT_MAKE 2000
// winix function and parameters have been parsed
// the request.status is OK
// (the winix function was not called yet)
#define WINIX_PREPARE_REQUEST 2000
// 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 2001
// 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 2002
// here you can attach your own session data (based on PluginDataBase class)
// call request.session->plugin_data.Assign(pointer)
@@ -31,6 +53,7 @@
#define WINIX_SESSION_CHANGED 3002
// the winix is closing
// the is not any session available (request->session is null)
#define WINIX_CLOSE 3004
// item was removed (rm function)
@@ -45,6 +68,29 @@
// PluginInfo::l1 is the dir id
#define WINIX_DIR_PREPARE_TO_REMOVE 3007
// winix is initialized,
// now you can initialize your plugin
#define WINIX_PLUGIN_INIT 3008
// 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")
#define WINIX_ADD_MOUNTS 3009
// add plugin functions here
#define WINIX_CREATE_FUNCTIONS 3010
// choose a default function
// if you do not select it then it will be choosen by winix
#define WINIX_SELECT_DEFAULT_FUNCTION 3011
// /etc/fstab has been changed
// now we have new mount points
#define WINIX_FSTAB_CHANGED 3012
// here you add your own template to notification system
// call system->notify.AddTemplate() method
// with a template file name
#define WINIX_NOTIFY_ADD_TEMPLATE 3013
#endif

View File

@@ -9,7 +9,8 @@
#include "postmultiparser.h"
#include "log.h"
#include "utf8.h"
#include "misc.h"
PostMultiParser::PostMultiParser()
@@ -238,16 +239,24 @@ size_t i;
void PostMultiParser::ReadContentSkipBoundary(bool has_boundary)
{
if( 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;
}
}
}
@@ -257,19 +266,25 @@ void PostMultiParser::ReadContentToFileLoop()
bool has_boundary = false;
while( last!=-1 && !(has_boundary=HasBoundary()) )
while( last!=-1 )
{
content += last;
content_len += 1;
ReadChar();
if( content.size() > WINIX_POSTMULTI_OUTPUT_BUFFER + boundary.size() + 2 ) // +2 for the new line character
if( HasBoundary() )
{
tmp_file.write(content.c_str(), WINIX_POSTMULTI_OUTPUT_BUFFER);
content_len += WINIX_POSTMULTI_OUTPUT_BUFFER;
content.erase(0, WINIX_POSTMULTI_OUTPUT_BUFFER);
has_boundary = true;
break;
}
if( config->post_file_max != 0 && content_len > (size_t)config->post_file_max )
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;
@@ -283,7 +298,6 @@ bool has_boundary = false;
if( !content.empty() )
{
tmp_file.write(content.c_str(), content.size());
content_len += content.size();
content.clear();
}
}
@@ -296,7 +310,7 @@ void PostMultiParser::ReadContentToFile()
time_t t1, t2;
content.clear();
content.reserve(WINIX_POSTMULTI_OUTPUT_BUFFER + boundary.size());
content.reserve(WINIX_POSTMULTI_OUTPUT_BUFFER);
content_len = 0;
t1 = time(0);
@@ -349,17 +363,29 @@ void PostMultiParser::ReadContent()
void PostMultiParser::AddNormalPostVar()
{
if( post_table->size() >= WINIX_POSTTABLE_MAXSIZE )
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;
}
std::pair<PostTable::iterator, bool> res = post_table->insert( std::make_pair(name, content) );
if( config->utf8 )
{
Ezc::UTF8ToWide(name, namew);
Ezc::UTF8ToWide(content, contentw);
}
else
{
AssignString(name, namew);
AssignString(content, contentw);
}
std::pair<PostTab::iterator, bool> res = post_tab->insert( std::make_pair(namew, contentw) );
bool added = res.second;
log << log2 << "PMP: POST var, name: \"" << name << "\"";
log << log2 << "PMP: POST var, name: \"" << namew << "\"";
if( !added )
log << log2 << " (skipped)";
@@ -370,19 +396,29 @@ void PostMultiParser::AddNormalPostVar()
void PostMultiParser::AddFilePostVar()
{
if( post_file_table->size() >= WINIX_POSTTABLE_MAXSIZE )
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;
}
post_file_temp.filename = filename;
if( config->utf8 )
{
Ezc::UTF8ToWide(name, namew);
Ezc::UTF8ToWide(filename, post_file_temp.filename);
}
else
{
AssignString(name, namew);
AssignString(filename, post_file_temp.filename);
}
post_file_temp.tmp_filename = tmp_filename;
std::pair<PostFileTable::iterator, bool> res = post_file_table->insert( std::make_pair(name, post_file_temp) );
std::pair<PostFileTab::iterator, bool> res = post_file_tab->insert( std::make_pair(namew, post_file_temp) );
bool added = res.second;
log << log2 << "PMP: POST FILE var, name: \"" << name << "\"";
log << log2 << "PMP: POST FILE var, name: \"" << namew << "\"";
if( !added )
log << log2 << " (skipped)";
@@ -437,29 +473,33 @@ void PostMultiParser::CheckBoundaryEnd()
void PostMultiParser::CreateTmpFile()
{
char buf[100];
wchar_t buf[1024];
size_t buf_len = sizeof(buf)/sizeof(wchar_t);
if( config->auth_tmp_dir.empty() )
if( config->upload_dir.empty() )
{
log << log1 << "PMP: auth_tmp_dir is not set in the config" << logend;
log << log1 << "PMP: upload_dir is not set in the config" << logend;
err = WINIX_ERR_CANT_CREATE_FILE;
return;
}
sprintf(buf, "%s/winix_%u_%d_%u", config->auth_tmp_dir.c_str(), (unsigned)getpid(), tmp_filename_postfix, rand());
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_file.open(buf, std::ios_base::binary | std::ios_base::out);
tmp_filename = buf;
Ezc::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: " << tmp_filename << logend;
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: " << tmp_filename << logend;
log << log3 << "PMP: using temporary file for the content: " << atmp_filename << logend;
}
@@ -496,7 +536,7 @@ void PostMultiParser::ReadPart()
if( err != WINIX_ERR_OK && !filename.empty() )
{
log << log1 << "PMP: deleting the tmp file: " << tmp_filename << logend;
unlink(tmp_filename.c_str());
RemoveFile(tmp_filename);
}
}
@@ -531,7 +571,8 @@ void PostMultiParser::ReadChar()
Error PostMultiParser::Parse(FCGX_Stream * in_, PostTable & post_table_, PostFileTable & post_file_table_)
Error PostMultiParser::Parse(FCGX_Stream * in_, PostTab & post_tab_, PostFileTab & post_file_tab_)
{
in = in_;
last = 0;
@@ -539,8 +580,8 @@ Error PostMultiParser::Parse(FCGX_Stream * in_, PostTable & post_table_, PostFil
line_end_dos = false;
in_buffer_ind = WINIX_POSTMULTI_INPUT_BUFFER;
in_buffer_len = WINIX_POSTMULTI_INPUT_BUFFER;
post_table = &post_table_;
post_file_table = &post_file_table_;
post_tab = &post_tab_;
post_file_tab = &post_file_tab_;
tmp_filename_postfix = 1;
ReadChar();
@@ -554,8 +595,8 @@ Error PostMultiParser::Parse(FCGX_Stream * in_, PostTable & post_table_, PostFil
if( err != WINIX_ERR_OK )
{
post_table->clear();
post_file_table->clear();
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;

View File

@@ -34,7 +34,7 @@ public:
~PostMultiParser();
void SetConfig(Config * pconfig);
Error Parse(FCGX_Stream * in_, PostTable & post_table_, PostFileTable & post_file_table_);
Error Parse(FCGX_Stream * in_, PostTab & post_tab_, PostFileTab & post_file_tab_);
private:
@@ -43,13 +43,14 @@ private:
FCGX_Stream * in;
unsigned char * in_buffer;
std::ofstream tmp_file;
std::string tmp_filename;
std::wstring tmp_filename;
std::string atmp_filename;
int tmp_filename_postfix;
size_t in_buffer_ind;
size_t in_buffer_len;
PostTable * post_table;
PostFileTable * post_file_table;
PostTab * post_tab;
PostFileTab * post_file_tab;
int last; // last read character
@@ -62,6 +63,7 @@ private:
Error err;
std::string name, filename;
std::wstring namew, contentw;
PostFile post_file_temp;
void LogFirst(const std::string & to_log, size_t len);

View File

@@ -14,7 +14,7 @@
#include <string>
#include "httpsimpleparser.h"
#include "requesttypes.h"
#include "misc.h"
@@ -22,7 +22,9 @@ class PostParser : public HttpSimpleParser
{
FCGX_Stream * in;
PostTable & post_table;
PostTab * post_tab;
std::wstring temp_name, temp_value;
bool input_as_utf8;
protected:
@@ -35,9 +37,20 @@ protected:
virtual void Parameter(std::string & name, std::string & value)
{
std::pair<PostTable::iterator, bool> res = post_table.insert( std::make_pair(name, value) );
if( input_as_utf8 )
{
Ezc::UTF8ToWide(name, temp_name);
Ezc::UTF8ToWide(value, temp_value);
}
else
{
AssignString(name, temp_name);
AssignString(value, temp_value);
}
std::pair<PostTab::iterator, bool> res = post_tab->insert( std::make_pair(temp_name, temp_value) );
log << log2 << "Method POST, name: \"" << name << "\", value: \"" << value << "\"";
log << log2 << "Method POST, name: \"" << temp_name << "\", value: \"" << temp_value << "\"";
if( res.second == false )
log << log2 << " (skipped)";
@@ -48,8 +61,24 @@ protected:
public:
PostParser(FCGX_Stream * in_, PostTable & post_table_) : in(in_), post_table(post_table_)
PostParser()
{
input_as_utf8 = false;
}
void UTF8(bool utf)
{
input_as_utf8 = utf;
}
void Parse(FCGX_Stream * in_, PostTab & post_tab_)
{
in = in_;
post_tab = &post_tab_;
HttpSimpleParser::Parse();
}
};

View File

@@ -24,12 +24,13 @@ void Rebus::SetRequest(Request * prequest)
bool Rebus::InitPair(int a, int b, Item & item)
{
char buffer[100];
wchar_t buffer[100];
size_t buffer_len = sizeof(buffer) / sizeof(wchar_t);
bool add = false;
if( a+b <= 15 )
{
sprintf(buffer, "%d+%d", a, b);
swprintf(buffer, buffer_len, L"%d+%d", a, b);
item.question = buffer;
item.answer = a+b;
add = true;
@@ -37,7 +38,7 @@ bool add = false;
if( a-b >= 0 )
{
sprintf(buffer, "%d-%d", a, b);
swprintf(buffer, buffer_len, L"%d-%d", a, b);
item.question = buffer;
item.answer = a-b;
add = true;
@@ -91,23 +92,23 @@ return &table[0] + i;
bool Rebus::IsAnswerOk(Rebus::Item * item, const std::string & answer)
bool Rebus::IsAnswerOk(Rebus::Item * item, const std::wstring & answer)
{
if( item == 0 )
return false;
char * end;
const char * a = answer.c_str();
wchar_t * end;
const wchar_t * a = answer.c_str();
a = SkipWhite(a);
int value = (int)strtol(a, &end, 10);
int value = (int)wcstol(a, &end, 10);
if( a == end )
// nothing has been read
return false;
log << log2 << "Rebus: your answer is: " << value << logend;
end = (char*)SkipWhite(end);
end = (wchar_t*)SkipWhite(end);
if( *end != 0 )
{
@@ -145,9 +146,7 @@ bool Rebus::CheckRebus()
return false;
}
std::string * answer = request->PostVar("rebus");
if( answer && IsAnswerOk(request->session->rebus_item, *answer) )
if( IsAnswerOk(request->session->rebus_item, request->PostVar(L"rebus")) )
return true;
log << log1 << "Rebus: rebus has an incorrect answer" << logend;

View File

@@ -25,7 +25,7 @@ public:
struct Item
{
int key;
std::string question;
std::wstring question;
int answer;
};
@@ -34,7 +34,7 @@ public:
void SetRequest(Request * prequest);
void Init();
Item * Rand();
bool IsAnswerOk(Item * item, const std::string & answer);
bool IsAnswerOk(Item * item, const std::wstring & answer);
bool CheckRebus();
private:

View File

@@ -7,18 +7,12 @@
*
*/
#include <ctime>
#include <sys/stat.h>
#include <unistd.h>
#include "request.h"
#include "getparser.h"
#include "postparser.h"
#include "cookieparser.h"
#include "log.h"
#include "plugin.h"
#include "misc.h"
#include "db.h"
#include "functions/functionbase.h"
@@ -27,7 +21,6 @@
Request::Request() : char_empty(0)
{
id = 0;
Clear();
}
@@ -37,24 +30,20 @@ void Request::SetConfig(Config * pconfig)
}
void Request::Init()
{
compress.Init();
}
void Request::ClearPostFileTmp()
{
// deleting temporary files (if exists)
while( !post_file_table.empty() )
while( !post_file_tab.empty() )
{
const std::string & tmp_filename = post_file_table.begin()->second.tmp_filename;
const std::wstring & tmp_filename = post_file_tab.begin()->second.tmp_filename;
if( unlink(tmp_filename.c_str()) == 0 )
if( RemoveFile(tmp_filename) )
log << log3 << "Request: deleted tmp file: " << tmp_filename << logend;
post_file_table.erase(post_file_table.begin());
post_file_tab.erase(post_file_tab.begin());
}
}
@@ -67,56 +56,47 @@ void Request::Clear()
if( ++id == 0 )
++id;
get_table.clear();
post_table.clear();
post_file_table.clear();
cookie_table.clear();
ClearPostFileTmp();
get_tab.clear();
post_tab.clear();
post_file_tab.clear();
cookie_tab.clear();
method = none;
role = responder;
headers.str("");
page.str("");
debug.str("");
notify.str("");
headers.Clear();
page.Clear();
debug.Clear();
env_request_method = &char_empty;
env_request_uri = &char_empty;
env_http_cookie = &char_empty;
env_remote_addr = &char_empty;
env_http_host = &char_empty;
env_http_user_agent = &char_empty;
env_request_method = &char_empty;
env_request_uri = &char_empty;
env_http_cookie = &char_empty;
env_remote_addr = &char_empty;
env_http_host = &char_empty;
env_http_user_agent = &char_empty;
env_fcgi_role = &char_empty;
env_content_type = &char_empty;
env_http_accept_encoding = &char_empty;
env_fcgi_role = &char_empty;
env_content_type = &char_empty;
session = 0;
item_table.clear();
item_tab.clear();
item.Clear();
dir_table.clear();
dir_tab.clear();
last_item = 0;
is_item = false;
pfunction = 0;
param_table.clear();
function = 0;
param_tab.clear();
status = WINIX_ERR_OK;
is_thread = false;
thread.Clear();
thread_tab.clear();
is_ticket = false;
ticket.Clear();
ticket_tab.clear();
notify_code = 0;
browser_msie = false;
redirect_to.clear();
x_sendfile.clear();
send_as_attachment = false;
plugin.Call(WINIX_REQUEST_CLEAR);
}
@@ -152,13 +132,13 @@ void Request::SetCookie(const char * name, long value, tm * expires)
bool Request::IsPostVar(const char * var)
bool Request::IsPostVar(const wchar_t * var)
{
PostTable::iterator p;
PostTab::iterator p;
p = post_table.find(var);
p = post_tab.find(var);
if( p == post_table.end() )
if( p == post_tab.end() )
return false;
return true;
@@ -166,23 +146,23 @@ return true;
std::string * Request::PostVar(const char * var)
const std::wstring & Request::PostVar(const wchar_t * var)
{
PostTable::iterator p = post_table.find(var);
PostTab::iterator p = post_tab.find(var);
if( p == post_table.end() )
return 0;
if( p == post_tab.end() )
return str_empty;
return &(p->second);
return p->second;
}
bool Request::PostVar(const char * var, std::string & result)
bool Request::PostVar(const wchar_t * var, std::wstring & result)
{
PostTable::iterator p = post_table.find(var);
PostTab::iterator p = post_tab.find(var);
if( p == post_table.end() )
if( p == post_tab.end() )
{
result.clear();
return false;
@@ -194,23 +174,29 @@ return true;
}
//
void Request::PrintGetTable()
std::wstring * Request::PostVarp(const wchar_t * var)
{
debug << "get_table: " << get_table.size() << "\n";
PostTab::iterator p = post_tab.find(var);
for(GetTable::iterator i = get_table.begin() ; i != get_table.end() ; ++i)
debug << " \"" << *i << "\"\n";
debug << std::endl;
if( p == post_tab.end() )
return 0;
return &p->second;
}
void Request::PrintGetTab()
{
debug << "get_tab: " << get_tab.size() << "\n";
for(GetTab::iterator i = get_tab.begin() ; i != get_tab.end() ; ++i)
debug << " \"" << *i << "\"\n";
debug << '\n';
}
/*
void Request::PrintEnv()
{
char ** e;
@@ -220,116 +206,16 @@ char ** e;
for( e = env ; *e ; ++e )
debug << ' ' << *e << "\n";
debug << std::endl;
}
void Request::PrintIn()
{
char buf[100];
int buf_len = sizeof(buf) / sizeof(char);
int len;
debug << "fcgi input:\n";
do
{
len = FCGX_GetStr(buf, buf_len - 1, in);
if( len != 0 )
{
buf[len] = 0;
debug << buf;
}
}
while( len == buf_len - 1 );
debug << std::endl;
}
const char * Request::SetEnvVar(const char * var)
{
const char * v = FCGX_GetParam(var, env);
if( v )
return v;
// char_empty contains '\0'
return &char_empty;
}
void Request::ReadEnvVariables()
{
// we store that values because FCGX_GetParam has O(n) complexity
// with this variables (env_*) we have O(1)
env_request_method = SetEnvVar("REQUEST_METHOD");
env_request_uri = SetEnvVar("REQUEST_URI");
env_http_cookie = SetEnvVar("HTTP_COOKIE");
env_remote_addr = SetEnvVar("REMOTE_ADDR");
env_http_host = SetEnvVar("HTTP_HOST");
env_http_user_agent = SetEnvVar("HTTP_USER_AGENT");
env_http_accept_encoding = SetEnvVar("HTTP_ACCEPT_ENCODING");
env_fcgi_role = SetEnvVar("FCGI_ROLE");
env_content_type = SetEnvVar("CONTENT_TYPE");
}
void Request::CheckIE()
{
char * msie = strstr(env_http_user_agent, "MSIE");
if( msie )
browser_msie = true;
else
browser_msie = false;
}
void Request::CheckKonqueror()
{
char * kon = strstr(env_http_user_agent, "Konqueror");
if( kon )
browser_konqueror = true;
else
browser_konqueror = false;
}
void Request::CheckMethod()
{
method = none;
if( ToSmall(env_request_method[0]) == 'g' )
method = get;
else
if( ToSmall(env_request_method[0]) == 'p' )
method = post;
// default we assume 'responder'
role = responder;
if( ToSmall(env_fcgi_role[0]) == 'a' )
role = authorizer;
debug << '\n';
}
*/
bool Request::AllPostVarEmpty()
{
PostTable::iterator i;
PostTab::iterator i;
for(i=post_table.begin() ; i!=post_table.end() ; ++i)
for(i=post_tab.begin() ; i!=post_tab.end() ; ++i)
if( !i->second.empty() )
return false;
@@ -338,224 +224,12 @@ return true;
// !! czy te parsery powinny byc skladowymi Request?
void Request::ReadParameters()
bool Request::IsParam(const wchar_t * param_name)
{
// !! wrzucic jako skladowa klasy
GetParser get_parser(env_request_uri, get_table);
get_parser.Parse();
if( method == post )
ParamTab::iterator i;
for(i=param_tab.begin() ; i!=param_tab.end() ; ++i)
{
if( IsSubStringNoCase("multipart/form-data", env_content_type) )
{
log << log3 << "Request: post content type: multipart/form-data" << logend;
post_multi_parser.SetConfig(config);
post_multi_parser.Parse(in, post_table, post_file_table);
}
else
{
// !! wrzucic jako skladowa klasy
PostParser post_parser(in, post_table);
post_parser.Parse();
}
}
CookieParser cookie_parser(env_http_cookie, cookie_table);
cookie_parser.Parse();
accept_encoding_parser.Parse(env_http_accept_encoding);
}
void Request::StandardLog()
{
log.PutDate(log1);
log << env_remote_addr << ' ' << env_request_method << ' ';
log << env_http_host << env_request_uri << ' ' << env_http_user_agent << logend;
}
// reading everything
void Request::Read()
{
ReadEnvVariables();
CheckMethod();
StandardLog();
ReadParameters();
CheckIE();
if( role == authorizer )
log << log3 << "Request: fast cgi role: authorizer" << logend;
CheckKonqueror();
}
void Request::SendSessionCookie()
{
if( !session || session->id==0 )
return;
if( !session->puser || !session->remember_me )
{
SetCookie(config->http_session_id_name.c_str(), session->id);
return;
}
time_t t = time(0) + config->session_remember_max_idle;
tm * expires = localtime(&t);
if( !expires )
{
// oops, something wrong
SetCookie(config->http_session_id_name.c_str(), session->id);
return;
}
SetCookie(config->http_session_id_name.c_str(), session->id, expires);
}
void Request::SendHeaders(bool compressing, Header header)
{
if( send_as_attachment )
FCGX_PutS("Content-Disposition: attachment\r\n", out);
if( !redirect_to.empty() )
{
FCGX_PutS("Status: 301 Moved Permanently\r\n", out);
FCGX_FPrintF(out, "Location: %s\r\n", redirect_to.c_str());
log << log2 << "Redirect to: " << redirect_to << logend;
}
else
if( !x_sendfile.empty() )
{
FCGX_FPrintF(out, "X-LIGHTTPD-send-file: %s\r\n", x_sendfile.c_str());
FCGX_PutS("Status: 200 OK\r\n", out);
log << log2 << "Sending file: " << x_sendfile << logend;
}
else
{
switch(header)
{
case h_404:
FCGX_PutS("Status: 404 Not Found\r\n", out);
FCGX_PutS("Content-Type: text/html\r\n", out);
log << log2 << "Request: response: 404 Not Found" << logend;
break;
case h_403:
FCGX_PutS("Status: 403 Forbidden\r\n", out);
FCGX_PutS("Content-Type: text/html\r\n", out);
log << log2 << "Request: response: 403 Forbidden" << logend;
break;
default:
FCGX_PutS("Status: 200 OK\r\n", out);
if( role != authorizer )
FCGX_PutS("Content-Type: text/html\r\n", out);
}
}
if( compressing )
FCGX_PutS("Content-Encoding: deflate\r\n", out);
FCGX_PutS(headers.str().c_str(), out);
FCGX_PutS("\r\n", out);
}
void Request::AddDebugInfo()
{
const std::string & d = debug.str();
if( !d.empty() )
{
page << "\n<!--\n";
page << d;
page << "\n-->\n";
}
}
// !! to powinno isc do kontrolera app
void Request::SendPage(bool compressing, const std::string & source_ref)
{
const std::string * source = &source_ref;
bool raw = is_item && item.content_type == Item::ct_raw && status == WINIX_ERR_OK &&
pfunction && (pfunction->fun.url == "cat" || pfunction->fun.url == "run");
if( config->html_filter && !raw )
{
html_filter.TrimWhite(true);
html_filter.BreakLines(60);
html_filter.InsertTabs(2);
html_filter.CheckOrphans(HTMLFilter::lang_pl, HTMLFilter::orphan_160space);
html_filter.Filter(*source, clean_html);
source = &clean_html;
}
if( compressing )
compress.CompressAndPut(source->c_str(), source->length(), out);
else
FCGX_PutS(source->c_str(), out);
}
void Request::SendAll()
{
const std::string & source = page.str();
Header header = h_200;
bool compressing = config->compression && role == responder && redirect_to.empty() && x_sendfile.empty() &&
!browser_msie && !browser_konqueror &&
accept_encoding_parser.AcceptDeflate() && source.size() >= 512;
if( status == WINIX_ERR_NO_ITEM || status == WINIX_ERR_NO_FUNCTION || status == WINIX_ERR_UNKNOWN_PARAM )
header = h_404;
if( status == WINIX_ERR_PERMISSION_DENIED || status == WINIX_ERR_CANT_CHANGE_USER || status == WINIX_ERR_CANT_CHANGE_GROUP )
header = h_403;
SendSessionCookie();
SendHeaders(compressing, header);
if( !redirect_to.empty() || !x_sendfile.empty() )
// if there is a redirect or a file to send then we do not send a content
return;
if( header == h_200 && role == authorizer && is_item && item.auth != Item::auth_none )
// if there is an item and the item has 'file' storage we do not send a content
return;
// adding debug info if exists
AddDebugInfo();
// sending content
SendPage(compressing, source);
}
bool Request::IsParam(const char * param_name)
{
ParamTable::iterator i;
for(i=param_table.begin() ; i!=param_table.end() ; ++i)
{
// !! make sure that exists std::string::operator==(const char*)
// (optimization)
if( i->name == param_name )
return true;
}
@@ -564,16 +238,28 @@ return false;
}
const std::string & Request::ParamValue(const char * param_name)
bool Request::IsParam(const std::wstring & param_name)
{
ParamTable::iterator i;
for(i=param_table.begin() ; i!=param_table.end() ; ++i)
ParamTab::iterator i;
for(i=param_tab.begin() ; i!=param_tab.end() ; ++i)
{
if( i->name == param_name )
return true;
}
return false;
}
const std::wstring & Request::ParamValue(const wchar_t * param_name)
{
ParamTab::iterator i;
for(i=param_tab.begin() ; i!=param_tab.end() ; ++i)
{
if( i->name == param_name )
{
return i->value;
}
}
return str_empty;

View File

@@ -13,25 +13,20 @@
#include <fcgiapp.h>
#include <sstream>
#include <vector>
#include <iomanip>
#include "requesttypes.h"
#include "session.h"
#include "item.h"
#include "error.h"
#include "thread.h"
#include "compress.h"
#include "acceptencodingparser.h"
#include "htmlfilter.h"
#include "postmultiparser.h"
#include "ticket.h"
#include "config.h"
#include "textstream.h"
#include "templates/htmltextstream.h"
class FunctionBase;
struct Request
{
// request id
@@ -40,23 +35,20 @@ struct Request
// it's used for some optimalizations e.g. in templates
size_t id;
FCGX_Stream * in, * out, * err;
FCGX_ParamArray env; // defined as 'char **'
enum Method { get, post, none } method;
// !! moze pozbyc sie tego none?
enum Method { get, post, head, none } method;
enum Role { responder, authorizer } role;
// headers, page and debug
// notify (for mailing)
std::ostringstream headers, page, debug, notify;
//std::ostringstream headers, page, debug;
TextStream<std::string> headers;
HtmlTextStream page, debug;
GetTable get_table;
PostTable post_table;
PostFileTable post_file_table;
CookieTable cookie_table;
// raw parameters
GetTab get_tab;
PostTab post_tab;
PostFileTab post_file_tab;
CookieTab cookie_tab;
// environment variables
// they are not null -- when the server doesn't have such a variable
@@ -78,124 +70,82 @@ struct Request
bool browser_konqueror;
// current session
// is set after calling session_manager.SetSession()
Session * session;
// current directory
std::vector<Item*> dir_table;
std::vector<Item*> dir_tab;
// true if a file exists
bool is_item;
// this item is used for many purposes such as editing, adding an item etc.
// current file (if exists)
Item item;
// current winix function
// null if there is no a function
FunctionBase * pfunction;
FunctionBase * function;
// parameters (name:value)
ParamTable param_table;
ParamTab param_tab;
// request status
Error status;
// last notify
int notify_code;
// items in the current directory
// maybe without contents?
std::vector<Item> item_table;
// current thread (if exists)
bool is_thread;
Thread thread;
std::vector<Thread> thread_tab;
// current ticket (if exists)
bool is_ticket;
Ticket ticket;
std::vector<Ticket> ticket_tab;
// usually items in the current directory (depends on the function)
std::vector<Item> item_tab;
// if not empty means an address for redirecting to
std::string redirect_to;
std::wstring redirect_to;
std::string aredirect_to;
// send header X-LIGHTTPD-send-file with path to a file
std::string x_sendfile;
std::wstring x_sendfile;
// send as attachment (causing header: content-disposition: attachment)
bool send_as_attachment;
// for debugging
void PrintGetTable();
void PrintEnv();
void PrintIn();
// this is a pointer either to the item (if exists) or to the last directory
Item * last_item;
Request();
void ClearPostFileTmp();
void SetConfig(Config * pconfig);
void Clear();
void Init();
// for debugging
void PrintGetTab();
//void PrintEnv();
bool IsParam(const char * param_name);
const std::string & ParamValue(const char * param_name); // returns empty string if there is no such a parameter
bool IsParam(const wchar_t * param_name);
bool IsParam(const std::wstring & param_name);
const std::wstring & ParamValue(const wchar_t * param_name); // returns empty string if there is no such a parameter
void SetCookie(const char * name, const char * value, tm * expires = 0);
void SetCookie(const char * name, long value, tm * expires = 0);
bool IsPostVar(const char * var);
std::string * PostVar(const char * var); // it can return null when there is no such a post variable
bool PostVar(const char * var, std::string & result);
bool IsPostVar(const wchar_t * var);
const std::wstring & PostVar(const wchar_t * var); // !! zamienic na referencje nie do sta³ej (bez const)
bool PostVar(const wchar_t * var, std::wstring & result);
std::wstring * PostVarp(const wchar_t * var);
bool AllPostVarEmpty(); // returning true if all post vars are empty
void ReadEnvVariables();
void CheckMethod();
void ReadParameters();
void Read();
void SendAll();
void SendNotify();
void SetConfig(Config * pconfig);
private:
Config * config;
enum Header
{
h_200,
h_404,
h_403
};
void ClearPostFileTmp();
bool CanUse(long user_id, const char * group_name);
void SendSessionCookie();
void CheckIE();
void CheckKonqueror();
void SendHeaders(bool compressing, Header header);
void AddDebugInfo();
void SendPage(bool compressing, const std::string & source_ref);
// used to set some env_* variables into it, when the server didn't set that variable
// it contains '\0'
// contains '\0'
// used to set env_* pointers to the empty value
const char char_empty;
// used in ParamValue(const char * param_name) when there is no such a param
const std::string str_empty;
PostMultiParser post_multi_parser;
const char * SetEnvVar(const char * var);
void StandardLog();
Compress compress;
AcceptEncodingParser accept_encoding_parser;
HTMLFilter html_filter;
// html after filtering
std::string clean_html;
// used in ParamValue() and PostVar() when there is no such a param
const std::wstring str_empty;
};

View File

@@ -20,25 +20,26 @@
struct PostFile
{
std::string filename; // original file name
std::string tmp_filename; // file with content (in /tmp)
std::wstring filename; // original file name
std::wstring tmp_filename; // file with content (in /tmp)
};
// parameters from get name:value
struct Param
{
std::string name;
std::string value;
std::wstring name;
std::wstring value;
};
// some global types used by Request class
typedef std::vector<std::string> GetTable;
typedef std::map<std::string, std::string> PostTable;
typedef std::map<std::string, PostFile> PostFileTable;
typedef std::map<std::string, std::string> CookieTable;
typedef std::vector<Param> ParamTable;
typedef std::vector<std::wstring> GetTab;
typedef std::map<std::wstring, std::wstring> PostTab;
typedef std::map<std::wstring, PostFile> PostFileTab;
typedef std::vector<Param> ParamTab;
typedef std::map<std::string, std::string> CookieTab;

View File

@@ -8,7 +8,7 @@
*/
#include "session.h"
#include "misc.h"
@@ -18,7 +18,7 @@ Session::Session()
Clear();
time = std::time(0);
tm_time = *std::localtime(&time);
tm_time = Time(time);
last_time = time;
tm_last_time = tm_time;
@@ -38,19 +38,6 @@ void Session::Clear()
remember_me = false;
new_session = true;
spam_score = 0;
// dir_old.clear();
}
bool Session::operator==(const Session & s) const
{
return id == s.id;
}
bool Session::operator<(const Session & s) const
{
return id < s.id;
}

View File

@@ -18,9 +18,13 @@
#include "rebus.h"
// when deleting Sessions you should set request.session into the session object as well
// this allows to delete plugins session data
// because a session object has plugin_data object
// and in its destructor the plugin.Call(WINIX_SESSION_REMOVE) is called
struct Session
{
// 0 - means that there is no session
// 0 - means that there is a temporary session
long id;
// true if the session was created now
@@ -51,21 +55,17 @@ struct Session
Rebus::Item * rebus_item;
bool rebus_checked;
//std::string dir_old;
int spam_score;
PluginData plugin_data;
// -------------------
Session();
void Clear();
bool operator==(const Session & s) const;
bool operator<(const Session & s) const;
void DecTimer(int & timer);
};

View File

@@ -9,15 +9,49 @@
#include "sessioncontainer.h"
#include "log.h"
#include "misc.h"
SessionContainer::SessionContainer()
{
request = 0;
table_size = 0;
work_mode = 1; // threading work mode
}
void SessionContainer::SetRequest(Request * prequest)
{
request = prequest;
}
void SessionContainer::SetConfig(Config * pconfig)
{
config = pconfig;
}
void SessionContainer::Clear()
{
table.clear();
Table::iterator i = table.begin();
// don't use table.clear();
// because plugins session data would not be erased
while( i != table.end() )
{
request->session = &(*i);
table.erase(i++);
}
// erasing indexes
index_id.clear();
index_time.clear();
table_size = 0;
request->session = 0;
}
@@ -27,9 +61,10 @@ void SessionContainer::SetLastContainer(LastContainer * plast_container)
}
SessionContainer::TableSize SessionContainer::Size()
size_t SessionContainer::Size()
{
return table.size();
// don't use table.size() as it has O(n) complexity on FreeBSD
return table_size;
}
@@ -54,16 +89,20 @@ Session & SessionContainer::Back()
bool SessionContainer::PushBack(const Session & session)
{
if( index_id.find(session.id) != index_id.end() )
// that element already exists
std::pair<IndexId::iterator, bool> index_id_res = index_id.insert( std::make_pair(session.id, table.end()) );
if( !index_id_res.second )
{
// that element already exists (was not inserted now)
return false;
}
Iterator last = table.insert(table.end(), session);
index_id.insert( std::make_pair(session.id, last) );
index_time.insert( std::make_pair(session.last_time, last) );
index_id_res.first->second = last;
table_size += 1;
log << log3 << "SC: added session, id: " << session.id << logend;
return true;
}
@@ -84,78 +123,92 @@ return i->second;
void SessionContainer::DelFirstByTimeInterval(time_t interval, bool skip_remember_flag)
{
IndexTime::iterator i = index_time.begin();
IndexTime::iterator iold;
time_t limit = std::time(0) - interval;
while( i != index_time.end() && i->second->last_time < limit )
{
long id = i->second->id;
iold = i;
++i; // incrementing before deleting old one
if( skip_remember_flag && iold->second->puser && iold->second->remember_me )
// don't delete sessions which have 'remember_me' flag (and a user is logged)
continue;
if( iold->second->puser )
last_container->UserLogout(iold->second->puser->id, iold->second->id);
// we're logging session.id (call this before table.erase())
DelFromIdIndex(iold->second);
table.erase(iold->second);
index_time.erase(iold);
log << log3 << "SC: deleted index_time for session id: " << id << logend;
log << log3 << "SC: deleted session, id: " << id << logend;
}
}
void SessionContainer::DelFromIdIndex(SessionContainer::Iterator iter)
/*
*
*
* sessions gc (another thread)
*
*
*/
void SessionContainer::Work()
{
bool exit = false;
IndexId::iterator i;
for( i = index_id.begin() ; i!=index_id.end() ; ++i)
{
if( i->second == iter )
{
index_id.erase(i);
log << log3 << "SC: deleted index_id for session id: " << iter->id << logend;
break;
Lock();
i = index_id.begin();
Unlock();
while( !exit )
{
Lock();
if( i == index_id.end() )
{
i = index_id.begin();
WaitForSignalSleep(30);
}
else
{
if( IsSessionOutdated(*i->second) )
DeleteSession(i++);
else
++i;
}
exit = synchro->was_stop_signal;
Unlock();
}
}
void SessionContainer::UpdateLastTime(SessionContainer::Iterator iter, time_t new_time)
// it's called from the other thread (with Lock and Unlock)
bool SessionContainer::IsSessionOutdated(const Session & s) const
{
IndexTime::iterator i = index_time.lower_bound(iter->last_time);
bool found = false;
bool outdated;
for( ; i != index_time.end() ; ++i)
{
if( i->second == iter )
{
index_time.erase(i);
index_time.insert( std::make_pair(new_time, iter) );
iter->last_time = new_time;
iter->tm_last_time = *std::localtime(&new_time);
log << log3 << "SC: last time and the time index for session id: " << iter->id << " updated" << logend;
found = true;
break;
}
}
if( s.remember_me )
outdated = s.last_time < std::time(0) - config->session_remember_max_idle;
else
outdated = s.last_time < std::time(0) - config->session_max_idle;
if( !found )
log << log1 << "SC: cannot update the time, time index not found for session id: " << iter->id << logend;
return outdated;
}
// it's called from the other thread (with Lock and Unlock)
void SessionContainer::DeleteSession(SessionContainer::IndexId::iterator i)
{
Session * old_session = request->session;
request->session = &(*i->second);
//log << log3 << "SessionContainer: deleting outdated session, id: " << i->second->id << logend;
if( i->second->puser )
last_container->UserLogout(i->second->puser->id, i->second->id);
table.erase(i->second);
index_id.erase(i);
table_size -= 1;
request->session = old_session;
}
/*
*
*
* end of sessions gc
*
*
*/

View File

@@ -10,57 +10,65 @@
#ifndef headerfilecmslucoresessioncontainer
#define headerfilecmslucoresessioncontainer
#include <list>
#include <map>
#include <ctime>
#include "session.h"
#include "lastcontainer.h"
#include "request.h"
#include "basethread.h"
#include "config.h"
class SessionContainer
class SessionContainer : public BaseThread
{
public:
typedef std::list<Session> Table;
typedef Table::iterator Iterator;
typedef Table::size_type TableSize;
public:
// when deleting Sessions you should set request.session into the session object
// this allows to delete plugins session data
// because a session object has plugin_data object
// and in its destructor the plugin.Call(WINIX_SESSION_REMOVE) is called
typedef std::list<Session> Table;
typedef Table::iterator Iterator;
typedef std::map<long, Iterator> IndexId;
typedef std::multimap<time_t, Iterator> IndexTime;
SessionContainer();
void SetRequest(Request * prequest);
void SetConfig(Config * pconfig);
void SetLastContainer(LastContainer * plast_container);
void Clear();
size_t Size();
Iterator Begin();
Iterator End();
Session & Back();
bool PushBack(const Session & session);
Iterator FindById(long);
private:
LastContainer * last_container;
Table table;
IndexId index_id;
IndexTime index_time;
void DelFromIdIndex(Iterator iter);
Request * request;
Config * config;
//void DelFromIdIndex(Iterator iter);
virtual void Work();
bool IsSessionOutdated(const Session & s) const;
void DeleteSession(IndexId::iterator i);
// in FreeBSD implementation (GCC) list::size() has linear complexity
// so we use our own table_size with O(1)
size_t table_size;
public:
void Clear();
TableSize Size();
Iterator Begin();
Iterator End();
Session & Back();
bool PushBack(const Session & session);
Iterator FindById(long);
void DelFirstByTimeInterval(time_t interval, bool skip_remember_flag = true);
void UpdateLastTime(Iterator iter, time_t new_time);
};

View File

@@ -22,19 +22,20 @@
SessionManager::SessionManager()
{
session_checker = 0;
}
void SessionManager::SetRequest(Request * prequest)
{
request = prequest;
session_tab.SetRequest(prequest);
}
void SessionManager::SetConfig(Config * pconfig)
{
config = pconfig;
session_tab.SetConfig(pconfig);
}
@@ -45,13 +46,25 @@ void SessionManager::SetSystem(System * psystem)
void SessionManager::SetLastContainer(LastContainer * plast_container)
{
session_table.SetLastContainer(plast_container);
session_tab.SetLastContainer(plast_container);
}
void SessionManager::SetSynchro(Synchro * psynchro)
{
session_tab.SetSynchro(psynchro);
}
size_t SessionManager::Size()
{
return session_tab.Size();
}
bool SessionManager::IsSession(long id)
{
if( session_table.FindById(id) == session_table.End() )
if( session_tab.FindById(id) == session_tab.End() )
return false;
return true;
@@ -92,19 +105,23 @@ return id;
void SessionManager::CreateTemporarySession()
{
SessionContainer::Iterator i = session_table.FindById( 0 );
SessionContainer::Iterator i = session_tab.FindById( 0 );
if( i == session_table.End() )
if( i == session_tab.End() )
{
Session s;
s.id = 0;
s.new_session = true;
session_table.PushBack(s);
request->session = &session_table.Back();
session_tab.PushBack(s);
request->session = &session_tab.Back();
}
else
{
request->session = &(*i);
request->session->Clear(); // !! what about session.plugin_data?
request->session->id = 0;
request->session->new_session = false;
}
}
@@ -115,23 +132,30 @@ void SessionManager::CreateSession()
Session s;
int attempts = 100;
for( ; attempts > 0 ; --attempts )
if( config->session_max == 0 || session_tab.Size() < config->session_max - 1 ) // -1 for the temporary session
{
s.id = CreateSessionId();
bool added = session_table.PushBack(s);
if( added )
for( ; attempts > 0 ; --attempts )
{
request->session = &session_table.Back();
request->session->new_session = true;
log << log2 << "SM: created a new session: " << request->session->id << logend;
s.id = CreateSessionId();
bool added = session_tab.PushBack(s);
return;
if( added )
{
request->session = &session_tab.Back();
request->session->new_session = true;
log << log2 << "SM: created a new session: " << request->session->id << logend;
return;
}
}
}
else
{
log << log2 << "SM: sessions limit exceeded (" << config->session_max << ")" << logend;
}
// there is a problem with generating a new session id
// we do not set a session cookie
CreateTemporarySession();
@@ -143,16 +167,17 @@ int attempts = 100;
bool SessionManager::SetSessionFromCookie(const std::string & cookie)
{
long id = atol(cookie.c_str());
SessionContainer::Iterator s = session_table.FindById(id);
long id = Tol(cookie.c_str());
SessionContainer::Iterator s = session_tab.FindById(id);
if( s == session_table.End() )
if( s == session_tab.End() )
return false;
// that session is in the table
request->session = &(*s);
request->session->new_session = false;
session_table.UpdateLastTime(s, std::time(0));
request->session->new_session = false;
request->session->last_time = std::time(0);
request->session->tm_last_time = Time(request->session->last_time);
if( request->method == Request::get )
request->session->last_time_get = request->session->last_time;
@@ -171,9 +196,9 @@ return true;
void SessionManager::SetSession()
{
CookieTable::iterator i = request->cookie_table.find(config->http_session_id_name);
CookieTab::iterator i = request->cookie_tab.find(config->http_session_id_name);
if( i == request->cookie_table.end() )
if( i == request->cookie_tab.end() )
{
CreateSession();
}
@@ -183,7 +208,7 @@ void SessionManager::SetSession()
{
// there is no such a session
// deleting the old cookie
request->cookie_table.erase(i);
request->cookie_tab.erase(i);
// and creating a new one
CreateSession();
@@ -205,48 +230,24 @@ void SessionManager::SetSession()
SessionContainer::Iterator SessionManager::SessionBegin()
{
return session_table.Begin();
return session_tab.Begin();
}
SessionContainer::Iterator SessionManager::SessionEnd()
{
return session_table.End();
return session_tab.End();
}
void SessionManager::DeleteOldSessions()
void SessionManager::DeleteSessions()
{
session_table.DelFirstByTimeInterval(config->session_max_idle);
if( ++session_checker > 1000 )
{
// we make the test after 1000 requests
log << log3 << "SM: checking sessions which have 'remember me' flag set" << logend;
session_checker = 0;
session_table.DelFirstByTimeInterval(config->session_remember_max_idle, false);
}
}
void SessionManager::DeleteAllPluginsData()
{
SessionContainer::Iterator i = session_table.Begin();
Session * old_session = request->session;
for( ; i!=session_table.End() ; ++i )
{
request->session = &(*i);
i->plugin_data.DeleteAll();
}
request->session = old_session;
session_tab.Clear();
}
@@ -261,10 +262,10 @@ SessionContainer::Iterator i;
sp.SetUsers(&system->users);
Session * old_session = request->session;
sp.Parse(config->session_file, session_table);
i = session_table.Begin();
sp.Parse(config->session_file, session_tab);
i = session_tab.Begin();
for( ; i!=session_table.End() ; ++i )
for( ; i!=session_tab.End() ; ++i )
{
i->plugin_data.Resize(plugin.Size());
request->session = &(*i);
@@ -294,9 +295,9 @@ void SessionManager::SaveSessions()
log << log2 << "SM: saving sessions" << logend;
long len = 0;
SessionContainer::Iterator i = session_table.Begin();
SessionContainer::Iterator i = session_tab.Begin();
for( ; i!=session_table.End() ; ++i )
for( ; i!=session_tab.End() ; ++i )
{
if( i->id != 0 && i->puser )
{
@@ -315,5 +316,24 @@ void SessionManager::SaveSessions()
void SessionManager::StartGC()
{
session_tab.StartThread();
}
// use it with Lock() and Unlock();
void SessionManager::PrepareToStopGC()
{
session_tab.WakeUpThread();
}
void SessionManager::WaitForGC()
{
session_tab.WaitForThread();
}

View File

@@ -18,6 +18,7 @@
#include "request.h"
#include "lastcontainer.h"
#include "system.h"
#include "synchro.h"
@@ -27,7 +28,7 @@ class SessionManager
Request * request;
System * system;
SessionContainer session_table;
SessionContainer session_tab;
bool IsSession(long s);
@@ -35,7 +36,6 @@ class SessionManager
void CreateTemporarySession();
void CreateSession();
bool SetSessionFromCookie(const std::string & cookie);
int session_checker;
public:
@@ -45,16 +45,21 @@ public:
void SetConfig(Config * pconfig);
void SetSystem(System * psystem);
void SetLastContainer(LastContainer * plast_container);
void SetSynchro(Synchro * psynchro);
void SetSession();
void DeleteAllPluginsData();
void DeleteOldSessions();
void DeleteSessions(); // deleting all sessions
void StartGC();
void PrepareToStopGC();
void WaitForGC();
void LoadSessions();
void SaveSessions();
SessionContainer::Iterator SessionBegin();
SessionContainer::Iterator SessionEnd();
size_t Size();
};

View File

@@ -9,6 +9,7 @@
#include "sessionparser.h"
#include "log.h"
#include "misc.h"
@@ -98,8 +99,8 @@ bool SessionParser::MakeSession(long user_id)
session.puser = puser;
session.new_session = true;
session.tm_time = *std::localtime(&session.time);
session.tm_last_time = *std::localtime(&session.last_time);
session.tm_time = Time(session.time);
session.tm_last_time = Time(session.last_time);
return true;
}

35
core/synchro.cpp Executable file
View File

@@ -0,0 +1,35 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "synchro.h"
Synchro::Synchro() : mutex(PTHREAD_MUTEX_INITIALIZER)
{
was_stop_signal = false;
}
bool Synchro::Lock()
{
return pthread_mutex_lock(&mutex) == 0;
}
void Synchro::Unlock()
{
pthread_mutex_unlock(&mutex);
}

36
core/synchro.h Executable file
View File

@@ -0,0 +1,36 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilecmslucoresynchro
#define headerfilecmslucoresynchro
#include <pthread.h>
struct Synchro
{
// one global mutex
pthread_mutex_t mutex;
// true when winix is closing
volatile bool was_stop_signal;
Synchro();
bool Lock();
void Unlock();
};
#endif

View File

@@ -10,9 +10,8 @@
#include "system.h"
#include "misc.h"
#include "error.h"
#include "notify.h"
#include "functions/functions.h"
#include "templates/templates.h"
#include "functions/functionbase.h"
@@ -34,59 +33,65 @@ void System::SetDb(Db * pdb)
}
void System::SetFunctions(Functions * pfunctions)
void System::SetSynchro(Synchro * psynchro)
{
functions = pfunctions;
synchro = psynchro;
}
void System::SetTemplates(Templates * ptemplates)
{
templates = ptemplates;
}
void System::Init()
{
dirs.SetDb(db);
dirs.SetRequest(request);
dirs.SetNotify(&notify);
dirs.ReadDirs();
mounts.SetDirs(&dirs);
mounts.SetDb(db);
mounts.SetRequest(request);
mounts.CreateMounts();
mounts.ReadMounts();
users.SetRequest(request);
users.ReadUsers(db);
users.SetTimeZoneOffset(config->time_zone_offset);
groups.ReadGroups(db); // !! chwilowe przekazanie argumentu, db bedzie zmienione
rebus.SetRequest(request);
rebus.Init();
notify.SetSynchro(synchro);
notify.SetRequest(request);
notify.SetConfig(config);
notify.SetUsers(&users);
notify.SetDirs(&dirs);
notify.Init();
thumb.SetSynchro(synchro);
thumb.SetDb(db);
thumb.SetConfig(config);
thumb.SetSystem(this);
}
// !! mozna zrobic jakas obsluge kiedy nie mozemy sie redirectnac, np gdy wystapil blad
// !! moze zwracac jakas wartosc?
void System::RedirectTo(const Item & item, const char * postfix)
void System::RedirectTo(const Item & item, const wchar_t * postfix)
{
request->redirect_to = config->base_url;
if( item.type == Item::dir )
{
// item_id is pointing to a directory
dirs.MakePath(item.id, path);
request->redirect_to += path;
dirs.MakePath(item.id, request->redirect_to, false);
}
else
{
if( !dirs.MakePath(item.parent_id, path) )
log << log1 << "Content: Can't redirect: no dirs for item id: " << item.id << logend;
request->redirect_to += path;
request->redirect_to += item.url;
// item_id is pointing to a file or a symlink
if( dirs.MakePath(item.parent_id, request->redirect_to, false) )
request->redirect_to += item.url;
}
if( postfix )
@@ -95,38 +100,34 @@ void System::RedirectTo(const Item & item, const char * postfix)
void System::RedirectTo(long item_id, const char * postfix)
void System::RedirectTo(long item_id, const wchar_t * postfix)
{
std::string path;
Item * pdir;
request->redirect_to = config->base_url;
pdir = dirs.GetDir(item_id);
Item * pdir = dirs.GetDir(item_id);
if( pdir )
{
// item_id is pointing to a directory
dirs.MakePath(pdir->id, path);
request->redirect_to += path;
dirs.MakePath(pdir->id, request->redirect_to, false);
}
else
{
// !! zrobic nowy interfejs
// !! GetItem pozamieniac na GetFile
// !! i nie uzywac request->item_table (zrobic sobie lokalny tutaj)
db->GetItem(request->item_table, item_id);
if( !request->item_table.empty() )
// item_id is pointing to a file
DbItemQuery iq;
iq.SetAllSel(false);
iq.WhereId(item_id);
iq.sel_parent_id = true;
iq.sel_url = true;
if( db->GetItem(item_temp, iq) == WINIX_ERR_OK )
{
if( !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->redirect_to += path + request->item_table[0].url;
if( dirs.MakePath(item_temp.parent_id, request->redirect_to, false) )
request->redirect_to += item_temp.url;
}
else
{
log << log1 << "Content: Can't redirect: no such item: id: " << item_id << logend;
log << log1 << "System: can't redirect: no such item: id: " << item_id << logend;
}
}
@@ -135,43 +136,80 @@ Item * pdir;
}
void System::RedirectTo(const std::wstring & url)
{
request->redirect_to = config->base_url;
if( !url.empty() && url[0] == '/' )
{
// absolute path
request->redirect_to += url;
}
else
{
// relative path
if( !request->dir_tab.empty() )
{
if( dirs.MakePath(request->dir_tab.back()->id, request->redirect_to, false) )
request->redirect_to += url;
}
else
{
request->redirect_to += '/';
request->redirect_to += url;
}
}
}
void System::AddParams(const ParamTab & param_tab, std::wstring & str, bool clear_str)
{
if( clear_str )
str.clear();
for(size_t i=0 ; i<param_tab.size() ; ++i)
{
str += '/';
str += param_tab[i].name;
if( !param_tab[i].value.empty() )
{
str += ':';
str += param_tab[i].value;
}
}
}
void System::RedirectWithFunctionAndParamsTo(const std::wstring & url)
{
RedirectTo(url);
if( !request->function )
return;
request->redirect_to += '/';
request->redirect_to += request->function->fun.url;
AddParams(request->param_tab, request->redirect_to, false);
}
void System::RedirectToLastDir()
{
// !! dac sprawdzenie czy istnieje
RedirectTo( *request->dir_table.back() );
if( !request->dir_tab.empty() )
RedirectTo( *request->dir_tab.back() );
}
void System::RedirectToLastItem()
{
if( request->is_item )
RedirectTo(request->item);
else
RedirectTo( *request->dir_table.back() );// !! dac sprawdzenie czy istnieje
if( request->last_item )
RedirectTo( *request->last_item );
}
void System::PrepareUrl(Item & item)
{
TrimWhite(item.url);
if( item.url.empty() )
item.url = item.subject; // if the subject is empty then the url will be corrected by CorrectUrlOnlyAllowedChar()
CorrectUrlOnlyAllowedChar(item.url);
if( functions->Find(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(), '_');
}
}
bool System::CanChangeUser(const Item & item, long new_user_id)
{
@@ -183,6 +221,8 @@ bool System::CanChangeUser(const Item & item, long new_user_id)
// super user is allowed everything
return true;
// !! przeciez to prosciej mozna zapisac
// albo dac od razu return false
if( item.user_id != new_user_id )
// only super user can change the owner of an item
return false;
@@ -333,13 +373,11 @@ bool System::HasReadExecAccessToPath(long dir_id)
}
bool System::DirsHaveReadExecPerm()
bool System::HasReadExecAccessToPath(const std::vector<Item*> & dir_tab)
{
std::vector<Item*>::iterator i;
for(i = request->dir_table.begin() ; i!=request->dir_table.end() ; ++i)
for(size_t i=0 ; i < dir_tab.size() ; ++i)
{
if( !HasReadExecAccess(**i) )
if( !HasReadExecAccess(*dir_tab[i]) )
return false;
}
@@ -347,16 +385,22 @@ return true;
}
bool System::DirsHaveReadExecPerm()
{
return HasReadExecAccessToPath(request->dir_tab);
}
// if we don't have access we only remove the item from the table
void System::CheckAccessToItems(std::vector<Item> & item_table)
void System::CheckAccessToItems(std::vector<Item> & item_tab)
{
size_t i = 0;
while( i < item_table.size() )
while( i < item_tab.size() )
{
if( !HasReadAccess(item_table[i]) )
if( !HasReadAccess(item_tab[i]) )
{
item_table.erase(item_table.begin() + i);
item_tab.erase(item_tab.begin() + i);
}
else
{
@@ -369,7 +413,7 @@ size_t i = 0;
bool System::CanUseHtml(long user_id)
{
return IsMemberOfGroup(user_id, "allow_html");
return IsMemberOfGroup(user_id, L"allow_html");
}
@@ -382,12 +426,12 @@ bool System::CanUseBBCode(long user_id)
bool System::CanUseRaw(long user_id)
{
return IsMemberOfGroup(user_id, "allow_raw");
return IsMemberOfGroup(user_id, L"allow_raw");
}
bool System::IsMemberOfGroup(long user_id, const char * group_name)
bool System::IsMemberOfGroup(long user_id, const wchar_t * group_name)
{
User * puser = users.GetUser(user_id);
@@ -395,7 +439,7 @@ bool System::IsMemberOfGroup(long user_id, const char * group_name)
return false;
if( puser->super_user )
return true;
return true; // !! ?? zakladamy ze administrator jest czlonkiem wszystkich grup? dlaczego?
long group = groups.GetGroupId(group_name);
@@ -403,122 +447,177 @@ bool System::IsMemberOfGroup(long user_id, const char * group_name)
// there is no such a group
return false;
if( puser->IsMemberOf(group) )
return true;
return false;
return puser->IsMemberOf(group);
}
bool System::MakePathSimpleFs(std::string & path, long dir_id, bool create_dir)
// the path depends on parent_id
bool System::CreateNewFileSimpleFs(Item & item)
{
if( config->auth_simplefs_dir.empty() )
{
log << log1 << "System: auth_simplefs_dir is not set in the config file" << logend;
return false;
}
if( !dirs.MakePath(dir_id, path) )
return false;
if( create_dir && !CreateDirs(config->auth_simplefs_dir, path, 0755) )
return false;
path.insert(0, config->auth_simplefs_dir);
return true;
}
// the path depends on id
bool System::MakePathHashFs(std::string & path, long id, bool create_dir)
{
char buffer[50];
char * hash = buffer;
// get 'id' as hexadecimal
buffer[0] = '0';
sprintf(buffer+1, "%lx", (unsigned long)id);
path = config->auth_hashfs_dir;
if( path.empty() )
{
log << log1 << "System: auth_hashfs_dir is not set in the config file" << logend;
return false;
}
path += '/';
// make sure that the length is even
if( (strlen(hash) & 1) != 0 )
hash = buffer + 1; // the first character was zero
// creating dirs without the last part
// the last part is a part of a file
for(size_t i=0 ; hash[i] != 0 ; i+=2)
{
path += hash[i];
path += hash[i+1];
if( hash[i+2] != 0 )
{
if( create_dir && !CreateDir(path, 0755) )
return false;
path += '/';
}
}
// one character more to make sure the path is unique
// (we can have a directory without the character)
path += "_";
return true;
}
// making a complete path to a static file
bool System::MakePath(const Item & item, std::string & path, bool create_dir)
{
bool res;
Mount * pmount = mounts.CalcMount(item.parent_id);
if( !pmount || pmount->fs == Mount::simplefs )
{
res = MakePathSimpleFs(path, item.parent_id, create_dir);
}
else
{
res = MakePathHashFs(path, item.id, create_dir);
}
bool res = dirs.MakePath(item.parent_id, item.file_path);
if( res )
path += item.url;
{
if( !item.file_path.empty() && item.file_path[0] == '/' )
item.file_path.erase(0, 1);
}
else
path.clear();
{
log << log1 << "System: CreateNewFileSimpleFs: can't create a path to item.id: " << item.id
<< ", item.parent_id: " << item.parent_id << logend;
}
return res;
}
bool System::MakePath(Item & item, bool create_dir)
// the path depends on id
bool System::CreateNewFileHashFs(Item & item)
{
return MakePath(item, item.auth_path, create_dir);
wchar_t buffer[50];
wchar_t * hash = buffer;
size_t buffer_len = sizeof(buffer)/sizeof(wchar_t);
// get 'id' as hexadecimal
buffer[0] = '0';
swprintf(buffer+1, buffer_len, L"%lx", (unsigned long)item.id);
item.file_path.clear();
// make sure that the length is even
if( (wcslen(hash) & 1) != 0 )
hash = buffer + 1; // the first character was zero
for(size_t i=0 ; hash[i] != 0 ; i+=2)
{
item.file_path += hash[i];
item.file_path += hash[i+1];
if( hash[i+2] != 0 )
item.file_path += '/';
}
// one character more to make sure the path is unique
// (we can have a directory without the character)
item.file_path += '_';
return true;
}
Error System::AddFile(Item & item)
// creating item.file_path and item.file_fs
// you should set file_type yourself
// this method uses: item.id, item.url, item.parent_id (for selecting a mountpoint)
bool System::CreateNewFile(Item & item)
{
bool res;
if( item.type != Item::file )
{
log << log1 << "System: CreateNewFile: the item should be a file" << logend;
return false;
}
Mount * pmount = mounts.CalcMount(item.parent_id);
if( !pmount || pmount->fs != mounts.MountFsHashfs() )
{
res = CreateNewFileSimpleFs(item);
item.file_fs = mounts.MountFsSimplefs();
}
else
{
res = CreateNewFileHashFs(item);
item.file_fs = mounts.MountFsHashfs();
}
if( res )
item.file_path += item.url;
else
item.file_path.clear();
return res;
}
// making a global file path (in the unix file system)
// you should call CreateNewFile before
bool System::MakeFilePath(const Item & item, std::wstring & path, bool thumb, bool create_dir, int chmod)
{
path.clear();
if( config->upload_dir.empty() )
{
log << log1 << "System: MakePath: upload_dir is not set in the config file" << logend;
return false;
}
if( item.file_path.empty() || item.file_type == WINIX_ITEM_FILETYPE_NONE )
{
log << log1 << "System: MakePath: this item has not a static file" << logend;
return false;
}
path = config->upload_dir;
if( item.file_fs == mounts.MountFsHashfs() )
path += L"/hashfs";
else
path += L"/simplefs";
if( thumb )
path += L"/thumb";
else
path += L"/normal";
if( create_dir && !CreateDirs(path, item.file_path, chmod, true) )
return false;
path += '/';
path += item.file_path;
return true;
}
// item can be a directory, file or a symlink
// if item is a directory then the path will be with a slash at the end
bool System::MakePath(const Item & item, std::wstring & path, bool clear_path)
{
bool res;
if( clear_path )
path.clear();
if( item.type == Item::dir )
{
res = dirs.MakePath(item.id, path);
}
else
{
res = dirs.MakePath(item.parent_id, path);
if( res )
path += item.url;
}
return res;
}
Error System::AddFile(Item & item, int notify_code)
{
if( item.type != Item::file )
return WINIX_ERR_FILE_EXPECTED;
Error status = db->AddItem(item);
@@ -528,7 +627,8 @@ Error System::AddFile(Item & item)
log << log2 << "System: added a new file, url: " << item.url << ", id: " << item.id
<< ", parent_id: " << item.parent_id << logend;
request->notify_code |= WINIX_NOTIFY_ITEM_ADD;
if( notify_code )
notify.ItemChanged(notify_code, item);
}
return status;
@@ -536,9 +636,10 @@ return status;
Error System::EditFile(Item & item, bool with_url)
Error System::EditFile(Item & item, bool with_url, int notify_code)
{
if( item.type == Item::dir )
if( item.type != Item::file )
return WINIX_ERR_FILE_EXPECTED;
if( request->session && request->session->puser )
@@ -552,38 +653,312 @@ Error System::EditFile(Item & item, bool with_url)
if( status == WINIX_ERR_OK )
{
TemplatesFunctions::pattern_cacher.UpdatePattern(item);
log << log2 << "System: modified an item" << logend;
request->notify_code |= WINIX_NOTIFY_ITEM_EDIT;
if( notify_code )
notify.ItemChanged(notify_code, item);
}
return status;
}
Error System::CheckSpecialFile(const Item & item)
time_t System::LocalTime(time_t gmt_time)
{
static std::string fstab = "fstab";
int time_offset;
Item * etc = dirs.GetEtcDir();
if( request->session && request->session->puser )
time_offset = request->session->puser->time_zone_offset;
else
time_offset = config->time_zone_offset_guest;
if( !etc )
return WINIX_NOTHING_TO_DO;
return gmt_time + (time_t)time_offset;
}
if( item.parent_id != etc->id )
return WINIX_NOTHING_TO_DO;
if( item.url == fstab )
tm System::LocalTime(const tm * ptm)
{
time_t t;
tm rtm;
t = Time(ptm);
t = LocalTime(t);
rtm = Time(t);
return rtm;
}
tm System::LocalTime(const tm & ptm)
{
return LocalTime(&ptm);
}
/*
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 or a symlink (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)
*/
int System::FollowLink(const std::vector<Item*> & current_dir_tab, const std::wstring & link_to,
std::vector<Item*> & out_dir_tab, Item & out_item)
{
link_to_temp = link_to; // copy the link because it can be from out_item (and will be cleared)
out_item.Clear();
int res = dirs.FollowLink(current_dir_tab, link_to_temp, out_dir_tab, name_temp);
if( res == 1 )
{
log << log3 << "System: reloading mount points" << logend;
Error status = mounts.ReadMounts(item.content);
templates->ReadNewIndexTemplates();
return status;
if( db->GetItem(out_dir_tab.back()->id, name_temp, out_item) == WINIX_ERR_OK )
return 1;
else
return 2;
}
return WINIX_NOTHING_TO_DO;
return res;
}
bool System::FollowAllLinksDirFound(std::vector<Item*> & out_dir_tab,
bool follow_dir_default, bool stop_on_link_redirect, bool check_access)
{
log << log3 << "System: link to a directory: ";
dirs.LogDir(out_dir_tab);
log << logend;
if( check_access && !HasReadExecAccessToPath(out_dir_tab) )
{
log << log1 << "System: no access to the directory structure" << logend;
return false;
}
if( !out_dir_tab.back()->link_to.empty() )
{
if( follow_dir_default )
{
if( !(stop_on_link_redirect && out_dir_tab.back()->link_redirect==1) )
link_to_temp = out_dir_tab.back()->link_to;
}
}
return true;
}
bool System::FollowAllLinksFileOrSymlinkFound(std::vector<Item*> & out_dir_tab, Item & out_item,
bool stop_on_link_redirect, bool check_access)
{
if( out_item.type == Item::symlink )
log << log3 << "System: link to a symlink: ";
else
log << log3 << "System: link to a file: ";
dirs.LogDir(out_dir_tab);
log << out_item.url << logend;
if( check_access && !HasReadExecAccessToPath(out_dir_tab) )
{
log << log1 << "System: no access to the directory structure" << logend;
return false;
}
if( out_item.type == Item::symlink )
{
if( out_item.link_to.empty() )
{
log << log1 << "System: symlink empty" << logend;
return false;
}
else
{
if( !check_access || HasReadAccess(out_item) )
{
if( !(stop_on_link_redirect && out_item.link_redirect==1) )
link_to_temp = out_item.link_to;
}
else
{
log << log1 << "System: no read access to the symlink" << logend;
return false;
}
}
}
return true;
}
/*
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)
(link_to can be a path to a symlink if stop_on_link_redirect is true)
error:
2 - incorrect link_to
3 - there is not a root dir
4 - current_dir_tab was empty
5 - limit of symlinks exceeded
6 - permission denied to a file/symlink or a directory (or a symlink is empty)
current_dir_tab can be the same container as out_dir_tab
link_to can be a relative path (without the first slash)
if follow_dir_default is true then directories with 'default' flags are followed as well
if stop_on_link_redirect is true then the method stops on a symbolic link (or a directory
with 'default' flag set) where the redirection should be done, you should check then whether
the out_item.back()->link_to is not empty (if the result was 0 ) or
whether out_item.type is symlink (if the result was 1)
to make the redirection
*/
int System::FollowAllLinks(const std::vector<Item*> & current_dir_tab, const std::wstring & link_to,
std::vector<Item*> & out_dir_tab, Item & out_item,
bool follow_dir_default, bool stop_on_link_redirect, bool check_access)
{
int res;
size_t level = 0;
link_to_temp = link_to;
if( current_dir_tab.empty() )
return 4;
do
{
if( ++level > config->symlinks_follow_max )
{
log << log1 << "System: the number of maximum symlinks exceeded ("
<< config->symlinks_follow_max << ")" << logend;
res = 5;
}
else
{
res = FollowLink(current_dir_tab, link_to_temp, out_dir_tab, out_item);
link_to_temp.clear();
if( res == 0 )
{
out_item.Clear();
res = FollowAllLinksDirFound(out_dir_tab, follow_dir_default, stop_on_link_redirect, check_access) ? 0 : 6;
}
else
if( res == 1 )
{
res = FollowAllLinksFileOrSymlinkFound(out_dir_tab, out_item, stop_on_link_redirect, check_access) ? 1 : 6;
}
else
{
log << log2 << "System: incorrect link: " << link_to << logend;
}
}
}
while( !link_to_temp.empty() );
return res;
}
// the same as FollowAllLinks but starts from the root directory
// link_to must begin with a slash (or can be empty then the root directory is returned)
int System::FollowAllLinks(const std::wstring & link_to,
std::vector<Item*> & out_dir_tab, Item & out_item,
bool follow_dir_default, bool stop_on_link_redirect, bool check_access)
{
if( !link_to.empty() && link_to[0] != '/' )
return 2;
if( root_follow_dir_tab.size() != 1 )
root_follow_dir_tab.resize(1);
Item * root_dir = dirs.GetRootDir();
if( !root_dir )
return 3;
root_follow_dir_tab[0] = root_dir;
return FollowAllLinks(root_follow_dir_tab, link_to,
out_dir_tab, out_item, follow_dir_default, stop_on_link_redirect, check_access);
}
// the same as FollowAllLinks but operates on request->dir_tab and request->item
// and returns bool
// the method is making a redirection if needed
bool System::FollowAllLinks(const std::wstring & link_to,
bool follow_dir_default, bool stop_on_link_redirect, bool check_access)
{
int res = FollowAllLinks(request->dir_tab, link_to, temp_follow_dir_tab, temp_follow_item,
follow_dir_default, stop_on_link_redirect, check_access);
bool ok = (res == 0 || res == 1);
if( ok )
{
request->dir_tab = temp_follow_dir_tab;
if( res == 0 )
{
request->is_item = false;
request->item.Clear();
request->last_item = request->dir_tab.back();
if( !request->dir_tab.back()->link_to.empty() )
RedirectTo(request->dir_tab.back()->link_to);
log << log3 << "System: current directory changed" << logend;
}
else
{
request->is_item = true;
request->item = temp_follow_item;
request->last_item = &request->item;
if( request->item.type == Item::symlink )
RedirectTo(request->item.link_to); // request->item.link_to is not empty
log << log3 << "System: current directory changed and the new file loaded" << logend;
}
mounts.CalcCurMount();
}
else
{
if( res == 5 || res == 6 )
request->status = WINIX_ERR_PERMISSION_DENIED;
else
request->status = WINIX_ERR_NO_ITEM;
}
return ok;
}

View File

@@ -7,23 +7,24 @@
*
*/
#ifndef headerfilecmslucorefs
#define headerfilecmslucorefs
#ifndef headerfilecmslucoresystem
#define headerfilecmslucoresystem
#include <ctime>
#include "dirs.h"
#include "mounts.h"
#include "db.h"
#include "db/db.h"
#include "request.h"
#include "config.h"
#include "users.h"
#include "groups.h"
#include "rebus.h"
#include "loadavg.h"
#include "synchro.h"
#include "thumb.h"
#include "notify/notify.h"
class Functions;
class Templates;
// file system
@@ -49,6 +50,12 @@ public:
// load averages
LoadAvg load_avg;
// notifications (by emails)
Notify notify;
// thumbnails (special thread)
Thumb thumb;
// the time when the winix starts
time_t system_start;
@@ -56,17 +63,18 @@ public:
void SetRequest(Request * prequest);
void SetConfig(Config * pconfig);
void SetDb(Db * pdb);
void SetFunctions(Functions * pfunctions);
void SetTemplates(Templates * ptemplates);
void SetSynchro(Synchro * psynchro);
void Init();
void RedirectTo(const Item & item, const char * postfix = 0);
void RedirectTo(long item_id, const char * postfix = 0);
void AddParams(const ParamTab & param_tab, std::wstring & str, bool clear_str = true);
void RedirectTo(const Item & item, const wchar_t * postfix = 0);
void RedirectTo(long item_id, const wchar_t * postfix = 0);
void RedirectTo(const std::wstring & url);
void RedirectWithFunctionAndParamsTo(const std::wstring & url);
void RedirectToLastDir();
void RedirectToLastItem(); // redirect to an item if exists or to the last directory
void PrepareUrl(Item & item);
bool CanChangeUser(const Item & item, long new_user_id);
bool CanChangeGroup(const Item & item, long new_group_id);
bool CanChangePrivileges(const Item & item, int new_priv);
@@ -76,34 +84,68 @@ public:
bool HasReadWriteAccess(const Item & item);
bool HasReadExecAccess(const Item & item);
bool HasReadExecAccessToPath(long dir_id);
bool HasReadExecAccessToPath(const std::vector<Item*> & dir_tab);
bool DirsHaveReadExecPerm();
void CheckAccessToItems(std::vector<Item> & item_table);
void CheckAccessToItems(std::vector<Item> & item_tab);
bool CanUseHtml(long user_id);
bool CanUseBBCode(long user_id);
bool CanUseRaw(long user_id);
bool IsMemberOfGroup(long user_id, const char * group_name);
bool IsMemberOfGroup(long user_id, const wchar_t * group_name);
bool MakePath(const Item & item, std::string & path, bool create_dir);
bool MakePath(Item & item, bool create_dir); // output path is: item.auth_path
// creating item.file_path and item.file_fs (the mountpoint where the item is located)
bool CreateNewFile(Item & item);
bool MakeFilePath(const Item & item, std::wstring & path, bool thumb = false, bool create_dir = false, int chmod = 0755);
Error AddFile(Item & item);
Error EditFile(Item & item, bool with_url = true);
bool MakePath(const Item & item, std::wstring & path, bool clear_path = true);
Error CheckSpecialFile(const Item & item);
Error AddFile(Item & item, int notify_code = 0);
Error EditFile(Item & item, bool with_url = true, int notify_code = 0);
// converting GMT time to local time (different for each user)
time_t LocalTime(time_t gmt_time);
tm LocalTime(const tm * ptm);
tm LocalTime(const tm & ptm);
int FollowLink(const std::vector<Item*> & current_dir_tab, const std::wstring & link_to,
std::vector<Item*> & out_dir_tab, Item & out_item);
int FollowAllLinks(const std::vector<Item*> & current_dir_tab, const std::wstring & link_to,
std::vector<Item*> & out_dir_tab, Item & out_item,
bool follow_dir_default = false, bool stop_on_link_redirect = false, bool check_access = true);
// starting from root dir
int FollowAllLinks(const std::wstring & link_to,
std::vector<Item*> & out_dir_tab, Item & out_item,
bool follow_dir_default = false, bool stop_on_link_redirect = false, bool check_access = true);
// using request->dir_tab and request->item
bool FollowAllLinks(const std::wstring & link_to,
bool follow_dir_default = false, bool stop_on_link_redirect = false, bool check_access = true);
private:
Request * request;
Config * config;
Db * db;
Functions * functions;
Templates * templates;
Synchro * synchro;
std::string path;
bool MakePathSimpleFs(std::string & path, long dir_id, bool create_dir);
bool MakePathHashFs(std::string & path, long id, bool create_dir);
Item item_temp;
std::wstring link_to_temp, name_temp;
// for FollowAllLinks
std::vector<Item*> temp_follow_dir_tab;
std::vector<Item*> root_follow_dir_tab;
Item temp_follow_item;
bool CreateNewFileSimpleFs(Item & item);
bool CreateNewFileHashFs(Item & item);
bool FollowAllLinksDirFound(std::vector<Item*> & out_dir_tab,
bool follow_dir_default, bool stop_on_link_redirect, bool check_access);
bool FollowAllLinksFileOrSymlinkFound(std::vector<Item*> & out_dir_tab, Item & out_item,
bool stop_on_link_redirect, bool check_access);
};

13
core/textstream.cpp Executable file
View File

@@ -0,0 +1,13 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "textstream.h"
#include "misc.h"

296
core/textstream.h Executable file
View File

@@ -0,0 +1,296 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfile_winix_core_textstream
#define headerfile_winix_core_textstream
#include <string>
#include "misc.h"
/*
a special class representing a stream buffer
similar to std::ostringstream
StringType can be either std::string or std::wstring
this class doesn't use UTF-8 in any kind
*/
template<class StringType>
class TextStream
{
public:
typedef typename StringType::value_type CharType;
typedef typename StringType::value_type char_type;
void Clear();
bool Empty() const;
size_t Size() const;
void Reserve(size_t len);
const StringType & Str() const;
const CharType * CStr() const;
TextStream & operator<<(const char * str);
TextStream & operator<<(const std::string * str);
TextStream & operator<<(const std::string & str);
TextStream & operator<<(const wchar_t * str);
TextStream & operator<<(const std::wstring * str);
TextStream & operator<<(const std::wstring & str);
TextStream & operator<<(char);
TextStream & operator<<(wchar_t);
TextStream & operator<<(int);
TextStream & operator<<(long);
TextStream & operator<<(unsigned int);
TextStream & operator<<(unsigned long);
TextStream & operator<<(double);
TextStream & operator<<(const void *);// printing a pointer
TextStream & Write(const char * buf, size_t len);
TextStream & Write(const wchar_t * buf, size_t len);
TextStream & write(const char * buf, size_t len); // for compatibility with standard library (Ezc uses it)
TextStream & write(const wchar_t * buf, size_t len);
protected:
StringType buffer;
};
template<class StringType>
void TextStream<StringType>::Clear()
{
buffer.clear();
}
template<class StringType>
bool TextStream<StringType>::Empty() const
{
return buffer.empty();
}
template<class StringType>
size_t TextStream<StringType>::Size() const
{
return buffer.size();
}
template<class StringType>
void TextStream<StringType>::Reserve(size_t len)
{
buffer.reserve(len);
}
template<class StringType>
const StringType & TextStream<StringType>::Str() const
{
return buffer;
}
template<class StringType>
const typename TextStream<StringType>::CharType * TextStream<StringType>::CStr() const
{
return buffer.c_str();
}
template<class StringType>
TextStream<StringType> & TextStream<StringType>::operator<<(const char * str)
{
AssignString(str, buffer, false);
return *this;
}
template<class StringType>
TextStream<StringType> & TextStream<StringType>::operator<<(const std::string * str)
{
AssignString(*str, buffer, false);
return *this;
}
template<class StringType>
TextStream<StringType> & TextStream<StringType>::operator<<(const std::string & str)
{
AssignString(str, buffer, false);
return *this;
}
template<class StringType>
TextStream<StringType> & TextStream<StringType>::operator<<(const wchar_t * str)
{
AssignString(str, buffer, false);
return *this;
}
template<class StringType>
TextStream<StringType> & TextStream<StringType>::operator<<(const std::wstring * str)
{
AssignString(*str, buffer, false);
return *this;
}
template<class StringType>
TextStream<StringType> & TextStream<StringType>::operator<<(const std::wstring & str)
{
AssignString(str, buffer, false);
return *this;
}
template<class StringType>
TextStream<StringType> & TextStream<StringType>::operator<<(char v)
{
buffer += v;
return *this;
}
template<class StringType>
TextStream<StringType> & TextStream<StringType>::operator<<(wchar_t v)
{
buffer += static_cast<CharType>(v);
return *this;
}
template<class StringType>
TextStream<StringType> & TextStream<StringType>::operator<<(int v)
{
wchar_t buf[50];
size_t len = sizeof(buf) / sizeof(wchar_t);
Toa(v, buf, len);
AssignString(buf, buffer, false);
return *this;
}
template<class StringType>
TextStream<StringType> & TextStream<StringType>::operator<<(long v)
{
wchar_t buf[50];
size_t len = sizeof(buf) / sizeof(wchar_t);
Toa(v, buf, len);
AssignString(buf, buffer, false);
return *this;
}
template<class StringType>
TextStream<StringType> & TextStream<StringType>::operator<<(unsigned int v)
{
wchar_t buf[50];
size_t len = sizeof(buf) / sizeof(wchar_t);
Toa(v, buf, len);
AssignString(buf, buffer, false);
return *this;
}
template<class StringType>
TextStream<StringType> & TextStream<StringType>::operator<<(unsigned long v)
{
wchar_t buf[50];
size_t len = sizeof(buf) / sizeof(wchar_t);
Toa(v, buf, len);
AssignString(buf, buffer, false);
return *this;
}
template<class StringType>
TextStream<StringType> & TextStream<StringType>::operator<<(double v)
{
char buf[50];
sprintf(buf, "%f", v);
AssignString(buf, buffer, false);
return *this;
}
template<class StringType>
TextStream<StringType> & TextStream<StringType>::operator<<(const void * v)
{
wchar_t buf[50];
size_t len = sizeof(buf) / sizeof(wchar_t);
buf[0] = '0';
buf[1] = 'x';
Toa(reinterpret_cast<unsigned long>(v), buf+2, len-2, 16);
AssignString(buf, buffer, false);
return *this;
}
template<class StringType>
TextStream<StringType> & TextStream<StringType>::Write(const char * buf, size_t len)
{
AssignString(buf, len, buffer, false);
return *this;
}
template<class StringType>
TextStream<StringType> & TextStream<StringType>::write(const char * buf, size_t len)
{
return Write(buf, len);
}
template<class StringType>
TextStream<StringType> & TextStream<StringType>::Write(const wchar_t * buf, size_t len)
{
AssignString(buf, len, buffer, false);
return *this;
}
template<class StringType>
TextStream<StringType> & TextStream<StringType>::write(const wchar_t * buf, size_t len)
{
return Write(buf, len);
}
#endif

View File

@@ -2,24 +2,30 @@
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2009, Tomasz Sowa
* Copyright (c) 2009-2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilecmslucorecorethread
#define headerfilecmslucorecorethread
#ifndef headerfile_winix_plugins_thread_thread
#define headerfile_winix_plugins_thread_thread
#include <string>
namespace Thread
{
class Thread
{
public:
long id;
long parent_id;
long file_id;
//long parent_id;
long dir_id;
bool closed;
@@ -32,7 +38,7 @@ public:
Item last_item;
// used when sorting
long sort;
unsigned long sort;
void Clear()
{
@@ -50,4 +56,10 @@ public:
};
} // namespace
#endif

309
core/thumb.cpp Executable file
View File

@@ -0,0 +1,309 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#include <ctime>
#include "thumb.h"
#include "utf8.h"
#include "log.h"
#include "system.h"
void Thumb::SetDb(Db * pdb)
{
db = pdb;
}
void Thumb::SetConfig(Config * pconfig)
{
config = pconfig;
}
void Thumb::SetSystem(System * psystem)
{
system = psystem;
}
// first thread (objects locked)
void Thumb::CreateThumb(const Item & item, size_t cx, size_t cy, int aspect_mode)
{
item_temp.file = item;
item_temp.cx = cx;
item_temp.cy = cy;
item_temp.aspect_mode = aspect_mode;
thumb_tab.insert(thumb_tab.end(), item_temp);
WakeUpThread();
}
// second thread (objects locked)
bool Thumb::SignalReceived()
{
return !thumb_tab.empty();
}
// second thread (objects not locked)
void Thumb::Do()
{
ThumbTab::iterator i;
bool end;
Lock();
i = thumb_tab.begin();
Unlock();
do
{
Lock();
if( i != thumb_tab.end() )
{
item_work = *i;
thumb_tab.erase(i++);
end = false;
}
else
{
end = true;
}
Unlock();
if( !end )
CreateThumbnail();
}
while( !end && !IsExitSignal() );
}
void Thumb::EscapePath(const std::string & path)
{
command << '"';
for(size_t i=0 ; i<path.size() ; ++i)
{
if( path[i] == '"' )
command << '\\';
command << path[i];
}
command << "\" ";
}
/*
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 Thumb::SelectAspect()
{
switch( item_work.aspect_mode )
{
case WINIX_THUMB_MODE_1:
command << item_work.cx;
break;
case WINIX_THUMB_MODE_3:
command << item_work.cx << "x" << item_work.cy;
break;
case WINIX_THUMB_MODE_4:
command << '"' << item_work.cx << "x" << item_work.cy << "^\"";
break;
case WINIX_THUMB_MODE_5:
command << '"' << item_work.cx << "x" << item_work.cy << "!\"";
break;
case WINIX_THUMB_MODE_6:
command << '"' << item_work.cx << "x" << item_work.cy << ">\"";
break;
case WINIX_THUMB_MODE_7:
command << '"' << item_work.cx << "x" << item_work.cy << "<\"";
break;
case WINIX_THUMB_MODE_2:
default:
command << "x" << item_work.cy;
break;
}
}
// second thread (objects are not locked)
bool Thumb::CreateCommand()
{
bool res;
command.Clear();
stream_tmp_path.Clear();
Lock();
Ezc::WideToUTF8(config->convert_cmd, tempa);
command << tempa << " -quiet -strip -thumbnail ";
SelectAspect();
command << " ";
if( system->MakeFilePath(item_work.file, src_path) )
{
Ezc::WideToUTF8(src_path, tempa);
EscapePath(tempa);
stream_tmp_path << config->upload_dir << L"/tmp/thumb_" << std::time(0);
Ezc::WideToUTF8(stream_tmp_path.Str(), string_tmp_patha);
EscapePath(string_tmp_patha);
res = true;
}
else
{
log << log1 << "Thumb: cannot create a source path" << logend;
res = false;
}
Unlock();
return res;
}
// second thread (objects are not locked)
void Thumb::SaveTmpThumbnail()
{
bool moved = false;
Lock();
// the file could have been changed especially when creating thumbnail lasted too long
iq.SetAll(false, false);
iq.sel_parent_id = true;
iq.sel_file = true;
iq.sel_url = true;
iq.sel_type = true;
iq.WhereId(item_work.file.id);
if( db->GetItem(item_work.file, iq) == WINIX_ERR_OK )
{
if( system->MakeFilePath(item_work.file, dst_path, true, true, config->upload_dirs_chmod) )
{
if( RenameFile(stream_tmp_path.Str(), dst_path) )
{
log << log3 << "Thumb: created a thumbnail: " << dst_path << logend;
db->EditHasThumbById(true, item_work.file.id);
moved = true;
}
else
{
log << log1 << "Thumb: cannot move a temporary file: " << stream_tmp_path.Str() << ", to: " << dst_path << logend;
}
}
else
{
log << log1 << "Thumb: cannot create a destination path" << logend;
}
}
if( !moved )
::RemoveFile(stream_tmp_path.Str());
Unlock();
}
// second thread (objects are not locked)
void Thumb::CreateThumbnail()
{
if( !CreateCommand() )
return;
int res = std::system(command.CStr());
if( res == 0 )
{
SaveTmpThumbnail();
}
else
{
Lock();
log << log3 << "Thumb: some problems with creating a thumbnail " << tempa
<< ", 'convert' process returned: " << res << logend;
Unlock();
}
}
// 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 Thumb::CreateThumbnail()
{
Ezc::WideToUTF8(item_work.source, sourcea);
Ezc::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 << "Thumb: created a thumbnail: " << dsta << logend;
Unlock();
}
}
DestroyMagickWand(wand);
MagickWandTerminus();
}
*/

97
core/thumb.h Executable file
View File

@@ -0,0 +1,97 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilecmslucorethumb
#define headerfilecmslucorethumb
#include <string>
#include <list>
#include "basethread.h"
#include "textstream.h"
#include "db/db.h"
#include "core/item.h"
#include "core/config.h"
class System;
// Width given, height automagically selected to preserve aspect ratio.
#define WINIX_THUMB_MODE_1 1
// Height given, width automagically selected to preserve aspect ratio.
#define WINIX_THUMB_MODE_2 2
// Maximum values of height and width given, aspect ratio preserved.
#define WINIX_THUMB_MODE_3 3
// Minimum values of width and height given, aspect ratio preserved.
#define WINIX_THUMB_MODE_4 4
// Width and height emphatically given, original aspect ratio ignored.
#define WINIX_THUMB_MODE_5 5
// Change as per widthxheight but only if an image dimension exceeds a specified dimension.
#define WINIX_THUMB_MODE_6 6
// Change dimensions only if both image dimensions are less than specified dimensions.
#define WINIX_THUMB_MODE_7 7
class Thumb : public BaseThread
{
public:
void CreateThumb(const Item & item, size_t cx, size_t cy, int aspect_mode);
void SetDb(Db * pdb);
void SetConfig(Config * pconfig);
void SetSystem(System * psystem);
private:
Db * db;
Config * config;
System * system;
struct ThumbItem
{
Item file;
size_t cx;
size_t cy;
int aspect_mode;
};
// queue of thumbnails to create
typedef std::list<ThumbItem> ThumbTab;
ThumbTab thumb_tab;
ThumbItem item_temp;
// only for second thread
ThumbItem item_work;
std::wstring src_path, dst_path;
std::string tempa, string_tmp_patha;
TextStream<std::string> command;
TextStream<std::wstring> stream_tmp_path;
DbItemQuery iq;
virtual bool SignalReceived();
virtual void Do();
bool CreateCommand();
void SaveTmpThumbnail();
void CreateThumbnail();
void SelectAspect();
void EscapePath(const std::string & path);
};
#endif

View File

@@ -1,58 +0,0 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilecmslucoreticket
#define headerfilecmslucoreticket
#include <string>
struct Ticket
{
long id;
long dir_id;
long parent_id;
unsigned int type;
unsigned int status;
unsigned int priority;
unsigned int category;
unsigned int expected;
unsigned int progress; // 0 - 100 (percentage)
// the first item (with the content for the ticket)
long item_id;
void Clear()
{
id = -1;
dir_id = -1;
parent_id = -1;
type = 0;
status = 0;
priority = 0;
category = 0;
expected = 0;
progress = 0;
item_id = -1;
}
Ticket()
{
Clear();
}
};
#endif

View File

@@ -27,8 +27,8 @@ public:
typedef typename Table::iterator Iterator;
typedef typename Table::size_type SizeType;
typedef typename std::map<long, SizeType> TableId;
typedef typename std::map<std::string, SizeType> TableName;
typedef typename std::map<long, SizeType> TableId;
typedef typename std::map<std::wstring, SizeType> TableName;
UGContainer();
@@ -41,10 +41,10 @@ public:
void Clear();
bool Is(long id);
bool Is(const std::string & name);
bool Is(const std::wstring & name);
Iterator FindId(long id);
Iterator FindName(const std::string & name);
Iterator FindName(const std::wstring & name);
Type & operator[](SizeType pos);
@@ -141,7 +141,7 @@ return true;
template<class Type>
bool UGContainer<Type>::Is(const std::string & name)
bool UGContainer<Type>::Is(const std::wstring & name)
{
typename TableName::iterator i = table_name.find(name);
@@ -167,7 +167,7 @@ return table.begin() + i->second;
template<class Type>
typename UGContainer<Type>::Iterator UGContainer<Type>::FindName(const std::string & name)
typename UGContainer<Type>::Iterator UGContainer<Type>::FindName(const std::wstring & name)
{
typename TableName::iterator i = table_name.find(name);
@@ -185,7 +185,7 @@ void UGContainer<Type>::AddIndexes(UGContainer<Type>::SizeType pos)
table_id.insert( std::make_pair(table[pos].id, pos) );
table_name.insert( std::make_pair(table[pos].name, pos) );
log << log2 << "UGCont: added indexes to: id: " << table[pos].id << ", name: " << table[pos].name << logend;
log << log4 << "UGCont: added indexes to: id: " << table[pos].id << ", name: " << table[pos].name << logend;
}
@@ -193,7 +193,7 @@ void UGContainer<Type>::AddIndexes(UGContainer<Type>::SizeType pos)
template<class Type>
void UGContainer<Type>::RebuildIndexes()
{
log << log2 << "UGCont: rebuilding indexes" << logend;
log << log4 << "UGCont: rebuilding indexes" << logend;
table_id.clear();
table_name.clear();
@@ -204,7 +204,7 @@ void UGContainer<Type>::RebuildIndexes()
for(i=0 ; i!=len ; ++i)
AddIndexes( i );
log << log2 << "UGCont: indexes rebuilt, table.size: " << table.size() << ", table_id.size: "
log << log4 << "UGCont: indexes rebuilt, table.size: " << table.size() << ", table_id.size: "
<< table_id.size() << ", table_name.size: " << table_name.size() << logend;
}

View File

@@ -17,16 +17,19 @@
struct User
{
long id;
std::string name;
std::wstring name;
bool super_user;
std::vector<long> groups;
std::string email;
int cms_notify;
int thread_notify;
std::wstring email;
int notify;
// !! currently all users have the same offset
// option in config: time_zone_offset
int time_zone_offset;
User()
{
Clear();
@@ -40,8 +43,8 @@ struct User
super_user = false;
groups.clear();
email.clear();
cms_notify = 0;
thread_notify = 0;
notify = 0;
time_zone_offset = 0;
}

View File

@@ -39,6 +39,17 @@ void Users::ReadUsers(Db * db)
}
void Users::SetTimeZoneOffset(int offset)
{
Table::Iterator i;
for(i=table.Begin() ; i!=table.End() ; ++i)
{
i->time_zone_offset = offset;
}
}
bool Users::AddUser(const User & user)
{
Table::Iterator i = table.PushBack(user);
@@ -47,7 +58,7 @@ return (i != table.End());
}
bool Users::IsUser(const std::string & name)
bool Users::IsUser(const std::wstring & name)
{
return table.Is(name);
}
@@ -64,7 +75,7 @@ return &(*i);
}
User * Users::GetUser(const std::string & name)
User * Users::GetUser(const std::wstring & name)
{
Table::Iterator i = table.FindName(name);
@@ -76,7 +87,7 @@ return &(*i);
long Users::GetUserId(const std::string & name)
long Users::GetUserId(const std::wstring & name)
{
User * puser = GetUser(name);
@@ -120,6 +131,12 @@ void Users::LoginUser(long user_id, bool remember_me)
if( !request->session )
return;
if( request->session->id == 0 )
{
log << log1 << "Users: cannot login a user on a temporary session" << logend;
return;
}
request->session->puser = GetUser(user_id);
request->session->spam_score = 0;

View File

@@ -15,7 +15,7 @@
#include "ugcontainer.h"
#include "lastcontainer.h"
#include "request.h"
#include "db.h"
#include "db/db.h"
class Users
@@ -39,11 +39,12 @@ public:
void Clear();
void ReadUsers(Db * db);
void SetTimeZoneOffset(int offset); // !! temporarily one time_zone for all users
bool AddUser(const User & user);
bool IsUser(const std::string & name);
bool IsUser(const std::wstring & name);
User * GetUser(long user_id);
User * GetUser(const std::string & name);
long GetUserId(const std::string & name);
User * GetUser(const std::wstring & name);
long GetUserId(const std::wstring & name);
Iterator Begin();
Iterator End();
SizeType Size();

View File

@@ -13,7 +13,7 @@
#define WINIX_VER_MAJOR 0
#define WINIX_VER_MINOR 4
#define WINIX_VER_REVISION 0
#define WINIX_VER_REVISION 5
#endif

20
db/Makefile.dep Executable file
View File

@@ -0,0 +1,20 @@
# DO NOT DELETE
db.o: db.h dbbase.h dbconn.h dbtextstream.h ../core/textstream.h
db.o: ../core/misc.h ../core/item.h ../core/error.h ../core/log.h
db.o: ../core/textstream.h dbitemquery.h ../core/item.h dbitemcolumns.h
db.o: ../core/user.h ../core/group.h ../core/thread.h ../core/dircontainer.h
db.o: ../core/ugcontainer.h ../core/log.h ../core/misc.h
dbbase.o: dbbase.h dbconn.h dbtextstream.h ../core/textstream.h
dbbase.o: ../core/misc.h ../core/item.h ../core/error.h ../core/log.h
dbbase.o: ../core/textstream.h ../core/log.h ../../ezc/src/utf8.h
dbconn.o: dbconn.h dbtextstream.h ../core/textstream.h ../core/misc.h
dbconn.o: ../core/item.h ../core/log.h ../core/error.h ../core/log.h
dbconn.o: ../core/textstream.h
dbitemcolumns.o: dbitemcolumns.h ../core/item.h dbbase.h dbconn.h
dbitemcolumns.o: dbtextstream.h ../core/textstream.h ../core/misc.h
dbitemcolumns.o: ../core/item.h ../core/error.h ../core/log.h
dbitemcolumns.o: ../core/textstream.h
dbitemquery.o: dbitemquery.h ../core/item.h
dbtextstream.o: dbtextstream.h ../core/textstream.h ../core/misc.h
dbtextstream.o: ../core/item.h ../../ezc/src/utf8.h

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

@@ -0,0 +1 @@
o = db.o dbbase.o dbconn.o dbitemcolumns.o dbitemquery.o dbtextstream.o

1450
db/db.cpp Executable file

File diff suppressed because it is too large Load Diff

118
db/db.h Executable file
View File

@@ -0,0 +1,118 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfile_winix_db_db
#define headerfile_winix_db_db
#include <vector>
#include <map>
#include <cstdio>
#include <ctime>
#include <cstring>
#include "dbbase.h"
#include "dbitemquery.h"
#include "dbitemcolumns.h"
#include "core/item.h"
#include "core/user.h"
#include "core/group.h"
#include "core/thread.h"
#include "core/dircontainer.h"
#include "core/ugcontainer.h"
class Db : public DbBase
{
public:
// !! przerobic tak aby GetItem zwracalo wszystkie pozycja
// !! GetFile tylko dla plikow
// !! GetDir tylko dla katalogow
// !! GetFile i GetDir beda uzywac GetItem
bool CheckUser(const std::wstring & login, const std::wstring & password, long & user_id);
Error AddUser(User & user, const std::wstring & password);
Error AddItem(Item & item);
Error EditItemById(Item & item, bool with_url = true);
Error EditItemByUrl(Item & item, bool with_url = true);
// !! nie zwracac zadnych kodow bledow?
void GetItems(std::vector<Item> & item_tab, const DbItemQuery & item_query);
void GetItems(std::vector<long> & item_tab, const DbItemQuery & item_query);
Error GetItem(Item & item, const DbItemQuery & item_query);
bool GetPriv(Item & item, long id);
Error EditPrivById(Item & item, long id);
Error EditParentUrlById(Item & item, long id);
Error EditFileById(const Item & item, long id); // file_path, file_fs, file_type
Error EditHasThumbById(bool has_thumb, long id);
Error DelDirById(long id);
Error EditSubjectById(Item & item, long id);
Error DelItem(const Item & item);
void GetDirs(DirContainer & dir_tab);
void GetUsers(UGContainer<User> & user_tab);
void GetGroups(UGContainer<Group> & group_tab);
// !! nowy interfejs
long Size(long parent_id, Item::Type type = Item::none);
Error GetItemById(long item_id, Item & item);
Error GetItem(long parent_id, const std::wstring & url, Item & item);
Error EditLinkItem(long id, const std::wstring & link_to, int link_redirect);
Error EditTemplateItemById(long id, const std::wstring & new_html_template);
long GetItemId(long parent_id, const std::wstring & url, Item::Type type);
long GetFileId(long parent_id, const std::wstring & url);
long GetDirId(long parent_id, const std::wstring & url);
Error AddHardLink(Item & item);
protected:
DbTextStream query, query_create_url;
std::wstring temp_url;
Item dir_temp;
bool AddItemCreateUrlSubject(Item & item);
Error AddItemIntoContent(Item & item);
Error AddItemIntoItem(Item & item);
Error EditItemInItem(Item & item, bool with_url);
Error EditItemInContent(Item & item);
Error EditItemGetIdsByUrl(Item & item);
long GetContentId(long item_id);
PGresult * GetItemsQuery(const DbItemQuery & iq, bool skip_other_sel = false);
Error DelItemDelItem(const Item & item);
Error DelItemDelContent(const Item & item);
Error IncrementContentRef(long content_id);
Error DecrementContentRef(long content_id);
};
#endif

429
db/dbbase.cpp Executable file
View File

@@ -0,0 +1,429 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#include <stdlib.h>
#include <limits.h>
#include <limits>
#include "dbbase.h"
#include "core/log.h"
#include "core/error.h"
#include "utf8.h"
DbBase::DbBase()
{
db_conn = 0;
log_queries = false;
}
void DbBase::SetConn(DbConn * conn)
{
db_conn = conn;
}
void DbBase::SetConn(DbConn & conn)
{
db_conn = &conn;
}
DbConn * DbBase::GetConn()
{
return db_conn;
}
void DbBase::LogQueries(bool log_q)
{
log_queries = log_q;
}
PGresult * DbBase::AssertQuery(const char * q)
{
if( log_queries )
log << log1 << "Db: executing query: " << q << logend;
bool bad_query = false;
PGresult * r = PQexec(db_conn->GetPgConn(), q);
if( !r )
{
bad_query = true;
if( PQstatus(db_conn->GetPgConn()) != CONNECTION_OK )
{
db_conn->AssertConnection();
r = PQexec(db_conn->GetPgConn(), q);
if( r )
bad_query = false;
}
}
if( bad_query )
{
log << log1 << "Db: Problem with this query: \"" << q << '\"' << logend;
log << log1 << "Db: " << PQerrorMessage(db_conn->GetPgConn()) << logend;
throw Error(WINIX_ERR_DB_INCORRECT_QUERY);
}
return r;
}
PGresult * DbBase::AssertQuery(const std::wstring & q)
{
return AssertQuery(q.c_str());
}
PGresult * DbBase::AssertQuery(const DbTextStream & query)
{
return AssertQuery(query.CStr());
}
void DbBase::AssertResult(PGresult * r, ExecStatusType t)
{
if( PQresultStatus(r) != t )
{
log << "Db: Incorrect result status: " << PQerrorMessage(db_conn->GetPgConn()) << logend;
throw Error(WINIX_ERR_DB_INCORRENT_RESULT_STATUS);
}
}
int DbBase::AssertColumn(PGresult * r, const char * column_name)
{
int c = PQfnumber(r, column_name);
if( c == -1 )
{
log << log1 << "Db: there is no column: " << column_name << logend;
throw Error(WINIX_ERR_DB_NO_COLUMN);
}
return c;
}
const char * DbBase::AssertValue(PGresult * r, int row, int col)
{
const char * res = PQgetvalue(r, row, col);
if( !res )
{
log << log1 << "Db: there is no such an item in the result, row:" << row << ", col:" << col << logend;
throw Error(WINIX_ERR_NO_ITEM);
}
return res;
}
const std::wstring & DbBase::AssertValueWide(PGresult * r, int row, int col)
{
const char * res = AssertValue(r, row, col);
static std::wstring temp_wide_value;
Ezc::UTF8ToWide(res, temp_wide_value);
return temp_wide_value;
}
void DbBase::AssertValueWide(PGresult * r, int row, int col, std::wstring & result)
{
const char * res = AssertValue(r, row, col);
Ezc::UTF8ToWide(res, result);
}
long DbBase::AssertValueLong(PGresult * r, int row, int col)
{
return strtol( AssertValue(r, row, col), 0, 10 );
}
int DbBase::AssertValueInt(PGresult * r, int row, int col)
{
return (int)strtol( AssertValue(r, row, col), 0, 10 );
}
bool DbBase::AssertValueBool(PGresult * r, int row, int col)
{
return strtol( AssertValue(r, row, col), 0, 10 ) != 0;
}
unsigned long DbBase::AssertValueULong(PGresult * r, int row, int col)
{
return strtoul( AssertValue(r, row, col), 0, 10 );
}
unsigned int DbBase::AssertValueUInt(PGresult * r, int row, int col)
{
return (unsigned int)strtoul( AssertValue(r, row, col), 0, 10 );
}
tm DbBase::AssertValueTm(PGresult * r, int row, int col)
{
return ConvertTime(AssertValue(r, row, col));
}
void DbBase::ClearResult(PGresult * r)
{
if( r )
PQclear(r);
}
bool DbBase::IsNull(PGresult * r, int row, int col)
{
return PQgetisnull(r, row, col) == 1;
}
int DbBase::Rows(PGresult * r)
{
// PQntuples - Returns the number of rows (tuples) in the query result. Because it returns
// an integer result, large result sets might overflow the return value on 32-bit operating systems.
return PQntuples(r);
}
int DbBase::Cols(PGresult * r)
{
// PQnfields - Returns the number of columns (fields) in each row of the query result.
return PQnfields(r);
}
long DbBase::AffectedRows(PGresult * r)
{
// PQcmdTuples - This function returns a string containing the number of rows affected by the SQL
// statement that generated the PGresult. This function can only be used following the execution
// of an INSERT, UPDATE, DELETE, MOVE, FETCH, or COPY statement, or [...]
char * rows_str = PQcmdTuples(r); // can be an empty string
long rows = 0;
if( rows_str )
{
rows = strtol(rows_str, 0, 10);
// strtol - If an overflow or underflow occurs, errno is set to ERANGE
// and the function return value is clamped according to the following table:
// Function underflow overflow
// strtol() LONG_MIN LONG_MAX
if( rows < 0 )
rows = 0;
}
return rows;
}
long DbBase::AssertCurrval(const char * table)
{
PGresult * r;
bquery.Clear();
bquery << R("select currval(")
<< table
<< R(");");
r = AssertQuery(bquery);
AssertResult(r, PGRES_TUPLES_OK);
if( Rows(r) != 1 )
{
log << log1 << "Db: error (currval) for table: " << table << ", " << PQerrorMessage(db_conn->GetPgConn()) << logend;
throw Error(WINIX_ERR_DB_ERR_CURRVAL);
}
return AssertValueLong(r, 0, 0);
}
tm DbBase::ConvertTime(const char * str)
{
tm t;
memset(&t, 0, sizeof(t));
if( !str )
return t;
size_t len = strlen(str);
if( len != 19 )
{
// the format must be like this: 2008-12-31 22:30:00
log << log1 << "DbBase: ConvertTime: unknown time format: \"" << str << "\"";
return t;
}
t.tm_year = Toi(str + 0) - 1900; /* year - 1900 */
t.tm_mon = Toi(str + 5) - 1; /* month of year (0 - 11) */
t.tm_mday = Toi(str + 8); /* day of month (1 - 31) */
t.tm_hour = Toi(str + 11); /* hours (0 - 23) */
t.tm_min = Toi(str + 14); /* minutes (0 - 59) */
t.tm_sec = Toi(str + 17); /* seconds (0 - 60) */
// t.tm_wday = 0; /* day of week (Sunday = 0) */
// t.tm_yday = 0; /* day of year (0 - 365) */
// t.tm_isdst = 0; /* is summer time in effect? */
// t.tm_zone = 0; // const_cast<char*>(""); /* abbreviation of timezone name */
return t;
}
const char * DbBase::ConvertTime(const tm & t)
{
// not thread safe
static char buffer[100];
sprintf(buffer, "%04d-%02d-%02d %02d:%02d:%02d",
t.tm_year + 1900,
t.tm_mon + 1,
t.tm_mday,
t.tm_hour,
t.tm_min,
t.tm_sec);
return buffer;
}
void DbBase::CreateIdList(const std::vector<long> & id_tab, std::wstring & list, bool add_parentheses)
{
wchar_t buffer[50];
size_t buffer_len = sizeof(buffer) / sizeof(wchar_t);
list.clear();
if( add_parentheses )
list += '(';
for(size_t i=0 ; i<id_tab.size() ; ++i)
{
swprintf(buffer, buffer_len, L"%lu", (unsigned long)id_tab[i]);
list += buffer;
if( i+1 < id_tab.size() )
list += ',';
}
if( add_parentheses )
list += ')';
}
Error DbBase::DoCommand(const DbTextStream & command)
{
PGresult * r = 0;
Error status = WINIX_ERR_OK;
try
{
r = AssertQuery(command);
AssertResult(r, PGRES_COMMAND_OK);
}
catch(const Error & e)
{
status = e;
}
ClearResult(r);
return status;
}
Error DbBase::DoCommand(const char * command)
{
PGresult * r = 0;
Error status = WINIX_ERR_OK;
try
{
r = AssertQuery(command);
AssertResult(r, PGRES_COMMAND_OK);
}
catch(const Error & e)
{
status = e;
}
ClearResult(r);
return status;
}
Error DbBase::BeginTrans()
{
return DoCommand("BEGIN;");
}
Error DbBase::RollbackTrans()
{
return DoCommand("ROLLBACK;");
}
Error DbBase::CommitTrans()
{
return DoCommand("COMMIT;");
}
Error DbBase::EndTrans(Error err)
{
if( err == WINIX_ERR_OK )
{
err = CommitTrans();
}
else
{
// we returned the old err code
RollbackTrans();
}
return err;
}

91
db/dbbase.h Executable file
View File

@@ -0,0 +1,91 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfile_winix_db_dbbase
#define headerfile_winix_db_dbbase
#include "dbconn.h"
#include "dbtextstream.h"
#include <vector>
#include <string>
#include "core/error.h"
class DbBase
{
public:
DbBase();
void SetConn(DbConn * conn);
void SetConn(DbConn & conn);
DbConn * GetConn();
void LogQueries(bool log_q);
PGresult * AssertQuery(const char * query);
PGresult * AssertQuery(const std::wstring & query);
PGresult * AssertQuery(const DbTextStream & query);
void AssertResult(PGresult * r, ExecStatusType t);
static int AssertColumn(PGresult * r, const char * column_name);
static const char * AssertValue(PGresult * r, int row, int col);
static const std::wstring & AssertValueWide(PGresult * r, int row, int col); // warning: this method uses a static buffer
static void AssertValueWide(PGresult * r, int row, int col, std::wstring & result);
static long AssertValueLong(PGresult * r, int row, int col);
static int AssertValueInt(PGresult * r, int row, int col);
static bool AssertValueBool(PGresult * r, int row, int col);
static unsigned long AssertValueULong(PGresult * r, int row, int col);
static unsigned int AssertValueUInt(PGresult * r, int row, int col);
static tm AssertValueTm(PGresult * r, int row, int col);
void ClearResult(PGresult * r);
long AssertCurrval(const char * table);
bool IsNull(PGresult * r, int row, int col);
int Rows(PGresult * r);
int Cols(PGresult * r);
long AffectedRows(PGresult * r);
static tm ConvertTime(const char * str);
static const char * ConvertTime(const tm & t); // warning: it uses its own static buffer
void CreateIdList(const std::vector<long> & id_tab, std::wstring & list, bool add_parentheses = true);
Error DoCommand(const DbTextStream & command);
Error DoCommand(const char * command);
Error BeginTrans();
Error RollbackTrans();
Error CommitTrans();
Error EndTrans(Error err);
protected:
// a helper method for escaping strings
template<class RawType>
DbTextStream::RawText<RawType> R(const RawType & par)
{
return DbTextStream::RawText<RawType>(par);
}
DbConn * db_conn;
bool log_queries;
private:
DbTextStream bquery;
};
#endif

153
db/dbconn.cpp Executable file
View File

@@ -0,0 +1,153 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "dbconn.h"
#include "core/log.h"
#include "core/error.h"
DbConn::DbConn()
{
pg_conn = 0;
}
DbConn::~DbConn()
{
Close();
}
PGconn * DbConn::GetPgConn()
{
return pg_conn;
}
void DbConn::SetConnParam(const std::string & d, const std::string & u, const std::string & p)
{
db_database = d;
db_user = u;
db_pass = p;
}
void DbConn::Connect()
{
Close();
conn_info.Clear();
conn_info.SetExtented(false);
conn_info << R("dbname=") << db_database
<< R(" user=") << db_user
<< R(" password=") << db_pass;
pg_conn = PQconnectdb(conn_info.CStr());
// warning! pg_conn can be not null but there cannnot be a connection established
// use PQstatus(pg_conn) to check whether the connection works fine
}
void DbConn::LogConnectionSocket()
{
log << log2 << "Db: connection to the database works fine" << logend;
log << log3 << "Db: connection socket: " << PQsocket(pg_conn) << logend;
}
void DbConn::WaitForConnection()
{
if( !pg_conn || PQstatus(pg_conn) != CONNECTION_OK )
{
log << log3 << "Db: waiting for the db to be ready...." << logend;
while( !AssertConnection(false, false) )
sleep(5);
LogConnectionSocket();
}
}
void DbConn::Close()
{
if( pg_conn )
{
PQfinish(pg_conn);
pg_conn = 0;
}
}
bool DbConn::AssertConnection(bool put_log, bool throw_if_no_connection)
{
bool was_connection = true;
if( !pg_conn )
{
was_connection = false;
Connect();
}
else
if( PQstatus(pg_conn) != CONNECTION_OK )
{
if( put_log )
log << log2 << "Db: connection to the database is lost, trying to recover" << logend;
was_connection = false;
PQreset(pg_conn);
}
if( pg_conn && PQstatus(pg_conn) == CONNECTION_OK )
{
if( !was_connection )
{
if( put_log )
LogConnectionSocket();
SetDbParameters();
}
return true;
}
else
{
if( put_log )
log << log1 << "Db: connection to db server cannot be established" << logend;
if( throw_if_no_connection )
throw Error(WINIX_ERR_DB_FATAL_ERROR_DURING_CONNECTING);
return false;
}
}
void DbConn::SetDbParameters()
{
if( PQsetClientEncoding(pg_conn, "UTF8") == -1 )
log << log1 << "Db: Can't set the proper client encoding" << logend;
}

55
db/dbconn.h Executable file
View File

@@ -0,0 +1,55 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfile_winix_db_dbconn
#define headerfile_winix_db_dbconn
#include <string>
#include <libpq-fe.h>
#include "dbtextstream.h"
class DbConn
{
public:
DbConn();
~DbConn();
void SetConnParam(const std::string & database, const std::string & user, const std::string & pass);
void Connect();
void WaitForConnection();
void Close();
bool AssertConnection(bool put_log = true, bool throw_if_no_connection = true);
void SetDbParameters();
PGconn * GetPgConn();
private:
void LogConnectionSocket();
PGconn * pg_conn;
std::string db_database, db_user, db_pass;
DbTextStream conn_info;
// a helper method for escaping strings
template<class RawType>
DbTextStream::RawText<RawType> R(const RawType & par)
{
return DbTextStream::RawText<RawType>(par);
}
};
#endif

77
db/dbitemcolumns.cpp Executable file
View File

@@ -0,0 +1,77 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "dbitemcolumns.h"
#include "dbbase.h"
void DbItemColumns::SetColumns(PGresult * r)
{
// PQfnumber returns -1 if there is no such a column
id = PQfnumber(r, "id");
user_id = PQfnumber(r, "user_id");
group_id = PQfnumber(r, "group_id");
privileges = PQfnumber(r, "privileges");
date_creation = PQfnumber(r, "date_creation");
date_modification = PQfnumber(r, "date_modification");
url = PQfnumber(r, "url");
type = PQfnumber(r, "type");
parent_id = PQfnumber(r, "parent_id");
content_id = PQfnumber(r, "content_id");
link_to = PQfnumber(r, "link_to");
link_redirect = PQfnumber(r, "link_redirect");
subject = PQfnumber(r, "subject");
content = PQfnumber(r, "content");
content_type = PQfnumber(r, "content_type");
guest_name = PQfnumber(r, "guest_name");
html_template = PQfnumber(r, "template");
modification_user_id = PQfnumber(r, "modification_user_id");
file_path = PQfnumber(r, "file_path");
file_fs = PQfnumber(r, "file_fs");
file_type = PQfnumber(r, "file_type");
has_thumb = PQfnumber(r, "has_thumb");
ref = PQfnumber(r, "ref");
modify_index = PQfnumber(r, "modify_index");
}
void DbItemColumns::SetItem(PGresult * r, long row, Item & item)
{
if( id != -1 ) item.id = DbBase::AssertValueLong(r, row, id);
if( user_id != -1 ) item.user_id = DbBase::AssertValueLong(r, row, user_id);
if( group_id != -1 ) item.group_id = DbBase::AssertValueLong(r, row, group_id);
if( privileges != -1 ) item.privileges = DbBase::AssertValueInt(r, row, privileges);
if( date_creation != -1 ) item.date_creation = DbBase::AssertValueTm(r, row, date_creation);
if( date_modification != -1 ) item.date_modification = DbBase::AssertValueTm(r, row, date_modification);
if( type != -1 ) item.type = static_cast<Item::Type>( DbBase::AssertValueInt(r, row, type) );
if( parent_id != -1 ) item.parent_id = DbBase::AssertValueLong(r, row, parent_id);
if( content_id != -1 ) item.content_id = DbBase::AssertValueLong(r, row, content_id);
if( link_redirect != -1 ) item.link_redirect = DbBase::AssertValueInt(r, row, link_redirect);
if( content_type != -1 ) item.content_type = static_cast<Item::ContentType>( DbBase::AssertValueInt(r, row, content_type) );
if( modification_user_id != -1 ) item.modification_user_id = DbBase::AssertValueLong(r, row, modification_user_id);
if( file_fs != -1 ) item.file_fs = DbBase::AssertValueInt(r, row, file_fs);
if( file_type != -1 ) item.file_type = DbBase::AssertValueInt(r, row, file_type);
if( has_thumb != -1 ) item.has_thumb = DbBase::AssertValueBool(r, row, has_thumb);
if( ref != -1 ) item.ref = DbBase::AssertValueInt(r, row, ref);
if( modify_index != -1 ) item.modify_index = DbBase::AssertValueInt(r, row, modify_index);
if( url != -1 ) DbBase::AssertValueWide(r, row, url, item.url);
if( content != -1 ) DbBase::AssertValueWide(r, row, content, item.content);
if( subject != -1 ) DbBase::AssertValueWide(r, row, subject, item.subject);
if( file_path != -1 ) DbBase::AssertValueWide(r, row, file_path, item.file_path);
if( link_to != -1 ) DbBase::AssertValueWide(r, row, link_to, item.link_to);
if( guest_name != -1 ) DbBase::AssertValueWide(r, row, guest_name, item.guest_name);
if( html_template != -1 ) DbBase::AssertValueWide(r, row, html_template, item.html_template);
}

55
db/dbitemcolumns.h Executable file
View File

@@ -0,0 +1,55 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfile_winix_db_dbitemcolumns
#define headerfile_winix_db_dbitemcolumns
#include <libpq-fe.h>
#include "core/item.h"
struct DbItemColumns
{
int id;
int user_id;
int group_id;
int privileges;
int date_creation;
int date_modification;
int url;
int type;
int parent_id;
int content_id;
int link_to;
int link_redirect;
int subject;
int content;
int content_type;
int guest_name;
int modification_user_id;
int html_template;
int file_path;
int file_fs;
int file_type;
int has_thumb;
int ref;
int modify_index;
void SetColumns(PGresult * r);
void SetItem(PGresult * r, long row, Item & item);
};
#endif

116
db/dbitemquery.cpp Executable file
View File

@@ -0,0 +1,116 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "dbitemquery.h"
DbItemQuery::DbItemQuery()
{
sort_asc = true;
SetAll(true, false);
id = -1;
parent_id = -1;
type = Item::none;
file_type = WINIX_ITEM_FILETYPE_NONE;
type_equal = true;
file_type_equal = true;
limit = 0; // limit and offset not used by default
offset = 0;
}
void DbItemQuery::SetAllSel(bool sel)
{
sel_parent_id = sel;
sel_user_id = sel;
sel_group_id = sel;
sel_guest_name = sel;
sel_privileges = sel;
sel_date = sel;
sel_subject = sel;
sel_content = sel;
sel_url = sel;
sel_type = sel;
sel_link = sel;
sel_file = sel;
sel_html_template = sel;
}
void DbItemQuery::SetAllWhere(bool where_)
{
where_id = where_;
where_parent_id = where_;
where_type = where_;
where_file_type = where_;
}
void DbItemQuery::SetAll(bool sel, bool where_)
{
SetAllSel(sel);
SetAllWhere(where_);
}
void DbItemQuery::WhereId(long id_)
{
where_id = true;
id = id_;
}
void DbItemQuery::WhereParentId(long parent_id_)
{
where_parent_id = true;
parent_id = parent_id_;
}
void DbItemQuery::WhereType(Item::Type type_, bool equal)
{
where_type = true;
type = type_;
type_equal = equal;
}
void DbItemQuery::WhereFileType(int file_t, bool equal)
{
where_file_type = true;
file_type = file_t;
file_type_equal = equal;
}
void DbItemQuery::Limit(long l)
{
limit = l;
}
void DbItemQuery::Offset(long o)
{
offset = o;
}

73
db/dbitemquery.h Executable file
View File

@@ -0,0 +1,73 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfile_winix_db_dbitemquery
#define headerfile_winix_db_dbitemquery
#include "core/item.h"
struct DbItemQuery
{
// id and content_id is selected always
bool sel_parent_id; // parent_id
bool sel_user_id; // user_id, modification_user_id
bool sel_group_id; // group_id
bool sel_guest_name; // guest_name
bool sel_privileges; // privileges
bool sel_date; // date_creation, date_modification
bool sel_subject; // subject
bool sel_content; // content, content_type, ref, modify_index
bool sel_url; // url
bool sel_type; // type (dir, file, none)
bool sel_link; // link_to, link_redirect
bool sel_file; // file_path, file_fs, file_type, has_thumb
bool sel_html_template; // template
bool where_id; //
bool where_parent_id; //
bool where_type;
bool where_file_type;
long id; // if where_id is true
long parent_id; // if where_parent_id is true
Item::Type type;
bool type_equal;
int file_type;
bool file_type_equal; // if true means file_type should be equal
bool sort_asc;
long limit;
long offset;
DbItemQuery();
void SetAllSel(bool sel);
void SetAllWhere(bool where_);
void SetAll(bool sel, bool where_);
void WhereId(long id_);
void WhereParentId(long parent_id_);
void WhereType(Item::Type type_, bool equal = true);
void WhereFileType(int file_t, bool equal = true);
void Limit(long l); // setting 0 turns off
void Offset(long o); // setting 0 turns off
};
#endif

537
db/dbtextstream.cpp Executable file
View File

@@ -0,0 +1,537 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "dbtextstream.h"
#include "utf8.h"
DbTextStream::DbTextStream()
{
was_param = false;
ext_escape = true;
}
void DbTextStream::SetExtented(bool ext)
{
ext_escape = ext;
}
/*
without escaping
*/
DbTextStream & DbTextStream::PutText(const char * str)
{
buffer += str;
was_param = false;
return *this;
}
DbTextStream & DbTextStream::PutText(const std::string * str)
{
return PutText(str->c_str());
}
DbTextStream & DbTextStream::PutText(const std::string & str)
{
return PutText(str.c_str());
}
DbTextStream & DbTextStream::PutText(const wchar_t * str)
{
Ezc::WideToUTF8(str, buffer, false);
was_param = false;
return *this;
}
DbTextStream & DbTextStream::PutText(const std::wstring * str)
{
return PutText(str->c_str());
}
DbTextStream & DbTextStream::PutText(const std::wstring & str)
{
return PutText(str.c_str());
}
DbTextStream & DbTextStream::operator<<(const RawText<const char*> & raw)
{
return PutText(raw.par);
}
DbTextStream & DbTextStream::operator<<(const RawText<const wchar_t*> & raw)
{
return PutText(raw.par);
}
DbTextStream & DbTextStream::operator<<(RawText<const std::string*> raw)
{
return PutText(raw.par);
}
DbTextStream & DbTextStream::operator<<(RawText<const std::wstring*> raw)
{
return PutText(raw.par);
}
DbTextStream & DbTextStream::operator<<(RawText<std::string> raw)
{
return PutText(raw.par);
}
DbTextStream & DbTextStream::operator<<(RawText<std::wstring> raw)
{
return PutText(raw.par);
}
DbTextStream & DbTextStream::operator<<(RawText<char> raw)
{
TextStream<std::string>::operator<<(raw.par);
was_param = false;
return *this;
}
DbTextStream & DbTextStream::operator<<(RawText<wchar_t> raw)
{
TextStream<std::string>::operator<<(raw.par);
was_param = false;
return *this;
}
DbTextStream & DbTextStream::operator<<(RawText<int> raw)
{
TextStream<std::string>::operator<<(raw.par);
was_param = false;
return *this;
}
DbTextStream & DbTextStream::operator<<(RawText<long> raw)
{
TextStream<std::string>::operator<<(raw.par);
was_param = false;
return *this;
}
DbTextStream & DbTextStream::operator<<(RawText<unsigned int> raw)
{
TextStream<std::string>::operator<<(raw.par);
was_param = false;
return *this;
}
DbTextStream & DbTextStream::operator<<(RawText<unsigned long> raw)
{
TextStream<std::string>::operator<<(raw.par);
was_param = false;
return *this;
}
DbTextStream & DbTextStream::operator<<(RawText<double> raw)
{
TextStream<std::string>::operator<<(raw.par);
was_param = false;
return *this;
}
DbTextStream & DbTextStream::operator<<(RawText<void*> raw)
{
TextStream<std::string>::operator<<(raw.par);
was_param = false;
return *this;
}
DbTextStream & DbTextStream::operator<<(const RawText<tm> & t)
{
buffer += ConvertTime(t.par);
was_param = false;
return *this;
}
/*
with escaping
*/
// !! sprawdzic jej dzialanie dla kolumn bytea (binarnych)
DbTextStream & DbTextStream::EBinPutChar(char c_)
{
char buf[10];
int c = (unsigned char)c_;
if( (c>=0 && c<=31) || c>=127 || c==39 || c==92 )
{
sprintf(buf, "\\\\%03o", c);
buffer += buf;
}
else
{
buffer += c;
}
return *this;
}
DbTextStream & DbTextStream::ETextPutChar(char c)
{
if( c == '\\' )
buffer += "\\\\";
else
if( c == '\'' )
buffer += "\\\'"; // don't use "''" because we use the method for PQconnectdb too
else
if( c != 0 )
buffer += c;
return *this;
}
DbTextStream & DbTextStream::ETextPutChar(wchar_t c)
{
if( c == '\\' )
buffer += "\\\\";
else
if( c == '\'' )
buffer += "\\\'"; // don't use "''" because we use the method for PQconnectdb too
else
if( c != 0 )
Ezc::IntToUTF8(int(c), buffer, false);
return *this;
}
DbTextStream & DbTextStream::EPutText(const char * str)
{
if( was_param )
buffer += ", ";
if( ext_escape )
buffer += 'E';
buffer += '\'';
for( ; *str ; ++str )
ETextPutChar(*str);
buffer += '\'';
was_param = true;
return *this;
}
DbTextStream & DbTextStream::EPutText(const std::string * str)
{
return EPutText(str->c_str());
}
DbTextStream & DbTextStream::EPutText(const std::string & str)
{
return EPutText(str.c_str());
}
DbTextStream & DbTextStream::EPutText(const wchar_t * str)
{
if( was_param )
buffer += ", ";
if( ext_escape )
buffer += 'E';
buffer += '\'';
for( ; *str ; ++str )
ETextPutChar(*str);
buffer += '\'';
was_param = true;
return *this;
}
DbTextStream & DbTextStream::EPutText(const std::wstring * str)
{
return EPutText(str->c_str());
}
DbTextStream & DbTextStream::EPutText(const std::wstring & str)
{
return EPutText(str.c_str());
}
// this method can escaped 0 in the middle of the string
DbTextStream & DbTextStream::EPutBin(const char * str, size_t len)
{
if( was_param )
buffer += ", ";
if( ext_escape )
buffer += 'E';
buffer += '\'';
for(size_t i = 0 ; i < len ; ++i)
EBinPutChar(str[i]);
buffer += '\'';
was_param = true;
return *this;
}
DbTextStream & DbTextStream::EPutBin(const std::string * str)
{
return EPutBin(str->c_str(), str->size());
}
DbTextStream & DbTextStream::EPutBin(const std::string & str)
{
return EPutBin(str.c_str(), str.size());
}
DbTextStream & DbTextStream::operator<<(const char * str)
{
return EPutText(str);
}
DbTextStream & DbTextStream::operator<<(const std::string * str)
{
return EPutText(str);
}
DbTextStream & DbTextStream::operator<<(const std::string & str)
{
return EPutText(str);
}
DbTextStream & DbTextStream::operator<<(const wchar_t * str)
{
return EPutText(str);
}
DbTextStream & DbTextStream::operator<<(const std::wstring * str)
{
return EPutText(str);
}
DbTextStream & DbTextStream::operator<<(const std::wstring & str)
{
return EPutText(str);
}
DbTextStream & DbTextStream::operator<<(char v)
{
if( was_param )
buffer += ", ";
if( ext_escape )
buffer += 'E';
buffer += '\'';
ETextPutChar(v);
buffer += '\'';
was_param = true;
return *this;
}
DbTextStream & DbTextStream::operator<<(wchar_t v)
{
if( was_param )
buffer += ", ";
if( ext_escape )
buffer += 'E';
buffer += '\'';
ETextPutChar(v);
buffer += '\'';
was_param = true;
return *this;
}
DbTextStream & DbTextStream::operator<<(int v)
{
if( was_param )
buffer += ", ";
TextStream<std::string>::operator<<(v);
was_param = true;
return *this;
}
DbTextStream & DbTextStream::operator<<(long v)
{
if( was_param )
buffer += ", ";
TextStream<std::string>::operator<<(v);
was_param = true;
return *this;
}
DbTextStream & DbTextStream::operator<<(unsigned int v)
{
if( was_param )
buffer += ", ";
TextStream<std::string>::operator<<(v);
was_param = true;
return *this;
}
DbTextStream & DbTextStream::operator<<(unsigned long v)
{
if( was_param )
buffer += ", ";
TextStream<std::string>::operator<<(v);
was_param = true;
return *this;
}
DbTextStream & DbTextStream::operator<<(double v)
{
if( was_param )
buffer += ", ";
TextStream<std::string>::operator<<(v);
was_param = true;
return *this;
}
DbTextStream & DbTextStream::operator<<(const void * v)
{
if( was_param )
buffer += ", ";
buffer += '\''; // !! not needed here?
TextStream<std::string>::operator<<(v);
buffer += '\'';
was_param = true;
return *this;
}
DbTextStream & DbTextStream::operator<<(const tm & t)
{
if( was_param )
buffer += ", ";
buffer += '\'';
buffer += ConvertTime(t);
buffer += '\'';
was_param = true;
return *this;
}
const char * DbTextStream::ConvertTime(const tm & t)
{
// not thread safe
static char buffer[100];
sprintf(buffer, "%04d-%02d-%02d %02d:%02d:%02d",
t.tm_year + 1900,
t.tm_mon + 1,
t.tm_mday,
t.tm_hour,
t.tm_min,
t.tm_sec);
return buffer;
}

167
db/dbtextstream.h Executable file
View File

@@ -0,0 +1,167 @@
/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfile_winix_db_dbtextstream
#define headerfile_winix_db_dbtextstream
#include <ctime>
#include "core/textstream.h"
/*
DbTextStream is used as a buffer for creating a database's query
By default all operators<< escape its string artuments. If you don't want
to escape an argument you should use a helper function R() (raw argument)
note: you have to define the function yourself, we do not provide it
because such a short name would make a mess in namespaces
sample:
create a helper function R as follows:
template<class RawType>
DbTextStream::RawText<RawType> R(const RawType & par)
{
return DbTextStream::RawText<RawType>(par);
}
now you can use DbTextStream in an easy way:
DbTextStream query;
std::string key = "some string";
query << R("select * from table where key=") << key << R(";");
in above example only the key is escaped.
Also with escaping operators<< insert commas between parameters, e.g.:
query << R("insert into table (key1, key2, key3) values (")
<< key1
<< key2
<< key3
<< R(");");
between key1 key2 and key3 are commas inserted automatically
*/
class DbTextStream : public TextStream<std::string>
{
public:
/*
a helper struct to select a proper operator<<
(for non-escaping versions of these operators)
*/
template<class RawType>
struct RawText
{
const RawType & par;
RawText(const RawText<RawType> & p) : par(p.par) {}
RawText(const RawType & p) : par(p) {}
};
DbTextStream();
// extented escaping: adding E character before the first quote e.g. E'string'
// default: true
void SetExtented(bool ext);
/*
without escaping
*/
DbTextStream & PutText(const char *);
DbTextStream & PutText(const std::string *);
DbTextStream & PutText(const std::string &);
DbTextStream & PutText(const wchar_t * str);
DbTextStream & PutText(const std::wstring * str);
DbTextStream & PutText(const std::wstring & str);
/*
we need this template operator for such calling:
dbtextstream_object << R("some string");
"some string" is actually a table (not a pointer)
*/
template<size_t str_size>
DbTextStream & operator<<(const RawText<char [str_size]> & raw) { return PutText(raw.par); }
template<size_t str_size>
DbTextStream & operator<<(const RawText<wchar_t [str_size]> & raw) { return PutText(raw.par); }
DbTextStream & operator<<(const RawText<const char*> & raw);
DbTextStream & operator<<(const RawText<const wchar_t*> & raw);
DbTextStream & operator<<(RawText<const std::string*> raw);
DbTextStream & operator<<(RawText<const std::wstring*> raw);
DbTextStream & operator<<(RawText<std::string> raw);
DbTextStream & operator<<(RawText<std::wstring> raw);
DbTextStream & operator<<(RawText<char> raw);
DbTextStream & operator<<(RawText<wchar_t> raw);
DbTextStream & operator<<(RawText<int> raw);
DbTextStream & operator<<(RawText<long> raw);
DbTextStream & operator<<(RawText<unsigned int> raw);
DbTextStream & operator<<(RawText<unsigned long> raw);
DbTextStream & operator<<(RawText<double> raw);
DbTextStream & operator<<(RawText<void*> raw);
DbTextStream & operator<<(const RawText<tm> & t);
/*
with escaping
*/
DbTextStream & EBinPutChar(char c);
DbTextStream & ETextPutChar(char c);
DbTextStream & ETextPutChar(wchar_t c);
DbTextStream & EPutText(const char * str);
DbTextStream & EPutText(const std::string * str);
DbTextStream & EPutText(const std::string & str);
DbTextStream & EPutText(const wchar_t * str);
DbTextStream & EPutText(const std::wstring * str);
DbTextStream & EPutText(const std::wstring & str);
DbTextStream & EPutBin(const char * str, size_t len);
DbTextStream & EPutBin(const std::string * str);
DbTextStream & EPutBin(const std::string & str);
DbTextStream & operator<<(const char * str);
DbTextStream & operator<<(const std::string * str);
DbTextStream & operator<<(const std::string & str);
DbTextStream & operator<<(const wchar_t * str);
DbTextStream & operator<<(const std::wstring * str);
DbTextStream & operator<<(const std::wstring & str);
DbTextStream & operator<<(char);
DbTextStream & operator<<(wchar_t);
DbTextStream & operator<<(int);
DbTextStream & operator<<(long);
DbTextStream & operator<<(unsigned int);
DbTextStream & operator<<(unsigned long);
DbTextStream & operator<<(double);
DbTextStream & operator<<(const void *);
DbTextStream & operator<<(const tm & t);
static const char * ConvertTime(const tm & t);
private:
bool was_param;
bool ext_escape;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1 @@
o = adduser.o cat.o chmod.o chown.o cp.o createthread.o createticket.o default.o download.o editticket.o emacs.o functionbase.o functionparser.o functions.o funthread.o funticket.o last.o login.o logout.o ls.o mkdir.o mv.o node.o priv.o privchanger.o readticket.o reload.o rm.o run.o subject.o uname.o upload.o who.o
o = adduser.o cat.o chmod.o chown.o ckeditor.o cp.o createthread.o default.o download.o emacs.o functionbase.o functionparser.o functions.o funthread.o last.o ln.o login.o logout.o ls.o mkdir.o mv.o node.o priv.o privchanger.o reload.o rm.o run.o specialdefault.o stat.o subject.o template.o tinymce.o uname.o upload.o uptime.o vim.o who.o

View File

@@ -17,37 +17,31 @@ namespace Fun
AddUser::AddUser()
{
fun.url = "adduser";
fun.url = L"adduser";
}
bool AddUser::CheckAddUserVars(const std::string * login, const std::string * pass, const std::string * conf_pass)
bool AddUser::CheckAddUserVars(const std::wstring & login, const std::wstring & pass, const std::wstring & conf_pass)
{
if( !login || !pass || !conf_pass )
{
request->status = WINIX_ERR_PERMISSION_DENIED;
return false;
}
if( login->empty() )
if( login.empty() )
{
request->status = WINIX_ERR_LOGIN_EMPTY;
return false;
}
if( *pass != *conf_pass )
if( pass != conf_pass )
{
request->status = WINIX_ERR_PASSWORDS_DIFFERENT;
return false;
}
if( pass->size() < 5 )
if( pass.size() < config->password_min_size )
{
request->status = WINIX_ERR_PASSWORD_TOO_SHORT;
return false;
}
if( system->users.IsUser(*login) )
if( system->users.IsUser(login) )
{
request->status = WINIX_ERR_USER_EXISTS;
return false;
@@ -65,20 +59,17 @@ void AddUser::MakePost()
{
User user;
std::string * login = request->PostVar("login");
std::string * pass = request->PostVar("password");
std::string * conf_pass = request->PostVar("confirmpassword");
std::string * email = request->PostVar("email");
const std::wstring & login = request->PostVar(L"login");
const std::wstring & pass = request->PostVar(L"password");
const std::wstring & conf_pass = request->PostVar(L"confirmpassword");
if( !CheckAddUserVars(login, pass, conf_pass) )
return;
user.name = *login;
user.name = login;
user.email = request->PostVar(L"email");
if( email )
user.email = *email;
request->status = db->AddUser(user, *pass);
request->status = db->AddUser(user, pass);
if( request->status == WINIX_ERR_OK )
{
@@ -87,11 +78,11 @@ User user;
if( !request->session->puser )
system->users.LoginUser(user.id, false);
log << log2 << "Content: added a new user: " << user.name << logend;
log << log2 << "Adduser: added a new user: " << user.name << logend;
}
else
{
log << log1 << "Content: I can't add to system->users: " << user.name
log << log1 << "Adduser: I can't add to system->users: " << user.name
<< " but the user was added to the db correctly" << logend;
}

View File

@@ -27,7 +27,7 @@ public:
private:
bool CheckAddUserVars(const std::string * login, const std::string * pass, const std::string * conf_pass);
bool CheckAddUserVars(const std::wstring & login, const std::wstring & pass, const std::wstring & conf_pass);
};

View File

@@ -16,7 +16,7 @@ namespace Fun
Cat::Cat()
{
fun.url = "cat";
fun.url = L"cat";
}
@@ -36,7 +36,7 @@ void Cat::MakeGet()
return;
}
request->send_as_attachment = request->IsParam("attachment");
request->send_as_attachment = request->IsParam(L"attachment");
}

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