summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog484
-rw-r--r--Makefile.in12
-rw-r--r--base.cpp65
-rw-r--r--base.h71
-rw-r--r--chat.cpp147
-rw-r--r--chat.h46
-rw-r--r--cmnd.cpp19
-rw-r--r--cmnd.h18
-rw-r--r--conf.cpp75
-rw-r--r--conf.h24
-rw-r--r--configure.in28
-rw-r--r--cont.cpp24
-rw-r--r--cont.h26
-rw-r--r--glob.h68
-rw-r--r--hmap.cpp180
-rw-r--r--hmap.h118
-rw-r--r--html.cpp140
-rw-r--r--html.h42
-rw-r--r--html/y_ani.gifbin0 -> 35107 bytes
-rw-r--r--incl.h16
-rw-r--r--lang.cpp78
-rw-r--r--lang.h24
-rw-r--r--logd.cpp65
-rw-r--r--logd.h24
-rw-r--r--main.cpp98
-rw-r--r--modl.cpp98
-rw-r--r--modl.h29
-rw-r--r--msgs.h36
-rw-r--r--mutx.cpp20
-rw-r--r--mutx.h21
-rw-r--r--name.cpp32
-rw-r--r--name.h28
-rw-r--r--pool.cpp214
-rw-r--r--pool.h77
-rw-r--r--reqp.cpp291
-rw-r--r--reqp.h47
-rw-r--r--room.cpp18
-rw-r--r--room.h34
-rw-r--r--s_chat.cpp10
-rw-r--r--s_chat.h26
-rw-r--r--s_conf.cpp10
-rw-r--r--s_conf.h26
-rw-r--r--s_html.cpp10
-rw-r--r--s_html.h26
-rw-r--r--s_lang.cpp10
-rw-r--r--s_lang.h26
-rw-r--r--s_modl.cpp10
-rw-r--r--s_modl.h26
-rw-r--r--s_mutx.cpp10
-rw-r--r--s_mutx.h26
-rw-r--r--s_sman.cpp10
-rw-r--r--s_sman.h26
-rw-r--r--s_sock.cpp10
-rw-r--r--s_sock.h26
-rw-r--r--s_tool.cpp111
-rw-r--r--s_tool.h19
-rw-r--r--sess.cpp35
-rw-r--r--sess.h28
-rw-r--r--sman.cpp48
-rw-r--r--sman.h32
-rw-r--r--sock.cpp238
-rw-r--r--sock.h53
-rw-r--r--thrd.cpp28
-rw-r--r--thrd.h26
-rw-r--r--todo.txt11
-rw-r--r--user.cpp170
-rw-r--r--user.h84
-rw-r--r--yChat-Perl-CGI/THIS_IS_LEGACY_SOFTWARE_AND_MIGHT_BE_BROKEN.txt2
-rw-r--r--yChat-Perl-CGI/ychat-0.2.1.zipbin0 -> 72514 bytes
-rw-r--r--yChat-Perl-CGI/ychat-0.2.2.zipbin0 -> 73682 bytes
-rw-r--r--yChat-Perl-CGI/ychat-0.2.3.zipbin0 -> 80044 bytes
-rw-r--r--yChat-Perl-CGI/ychat-0.2.4a.zipbin0 -> 81563 bytes
-rw-r--r--yChat-Perl-CGI/ychat-0.2.4c.zipbin0 -> 81809 bytes
-rw-r--r--yChat-Perl-CGI/ychat-0.2.5a2.zipbin0 -> 84947 bytes
-rw-r--r--yChat-Perl-CGI/ychat-0.2.6a.zipbin0 -> 84715 bytes
-rw-r--r--yChat-Perl-CGI/ychat-0.4.0a.zipbin0 -> 85353 bytes
-rw-r--r--yChat-Perl-CGI/ychat-0.4.1.zipbin0 -> 87361 bytes
-rw-r--r--yChat-Perl-CGI/ychat-0.4.2.zipbin0 -> 38558 bytes
-rw-r--r--yChat-Perl-CGI/ychat-0.4.3a.zipbin0 -> 39762 bytes
-rw-r--r--yChat-Perl-CGI/ychat-0.4.4a3.zipbin0 -> 41120 bytes
-rw-r--r--yChat-Perl-CGI/ychat-0.4.5a.zipbin0 -> 54688 bytes
-rw-r--r--yChat-Perl-CGI/ychat-0.4.6.zipbin0 -> 55180 bytes
-rw-r--r--yChat-Perl-CGI/ychat-0.4.7a2.zipbin0 -> 58931 bytes
-rw-r--r--yChat-Perl-CGI/ychat-0.4.8a2.zipbin0 -> 59105 bytes
-rw-r--r--yChat-Perl-CGI/ychat-0.4.9.zipbin0 -> 64276 bytes
-rw-r--r--yChat-Perl-CGI/ychat-0.6.0.zipbin0 -> 67379 bytes
-rw-r--r--yChat-Perl-CGI/ychat-0.6.1.zipbin0 -> 66562 bytes
-rw-r--r--yChat-Perl-CGI/ychat-0.6.2.zipbin0 -> 63478 bytes
-rw-r--r--yChat-Perl-Socket/THIS_IS_LEGACY_SOFTWARE_AND_MIGHT_BE_BROKEN.txt2
-rw-r--r--yChat-Perl-Socket/ychat-0.7.1.zipbin0 -> 48438 bytes
-rw-r--r--yChat-Perl-Socket/ychat-0.7.2.zipbin0 -> 40614 bytes
-rw-r--r--yChat-Perl-Socket/ychat-0.7.6.zipbin0 -> 61017 bytes
-rw-r--r--yChat-Perl-Socket/ychat-0.8.0.tar.gzbin0 -> 53873 bytes
-rw-r--r--yChat-Perl-Socket/ychat-0.8.1.tar.gzbin0 -> 37632 bytes
-rw-r--r--yChat/THIS_IS_LEGACY_SOFTWARE_AND_MIGHT_BE_BROKEN.txt2
-rw-r--r--yChat/desc/BRANCH_0_11
-rw-r--r--yChat/desc/BRANCH_0_21
-rw-r--r--yChat/desc/BRANCH_0_31
-rw-r--r--yChat/desc/BRANCH_0_41
-rw-r--r--yChat/desc/BRANCH_0_51
-rw-r--r--yChat/desc/BRANCH_0_61
-rw-r--r--yChat/desc/BRANCH_0_71
-rw-r--r--yChat/desc/BRANCH_0_81
-rw-r--r--yChat/ychat-0.1.tar.bz2bin0 -> 170155 bytes
-rw-r--r--yChat/ychat-0.2.tar.bz2bin0 -> 171220 bytes
-rw-r--r--yChat/ychat-0.3.tar.bz2bin0 -> 216371 bytes
-rw-r--r--yChat/ychat-0.4.tar.bz2bin0 -> 220406 bytes
-rw-r--r--yChat/ychat-0.5.0.tar.bz2bin0 -> 145903 bytes
-rw-r--r--yChat/ychat-0.5.1.tar.bz2bin0 -> 148333 bytes
-rw-r--r--yChat/ychat-0.5.2.tar.bz2bin0 -> 221718 bytes
-rw-r--r--yChat/ychat-0.5.3.tar.bz2bin0 -> 145031 bytes
-rw-r--r--yChat/ychat-0.5.4.tar.bz2bin0 -> 144531 bytes
-rw-r--r--yChat/ychat-0.5.5.tar.bz2bin0 -> 110132 bytes
-rw-r--r--yChat/ychat-0.6.0.tar.bz2bin0 -> 153809 bytes
-rw-r--r--yChat/ychat-0.7.0.tar.bz2bin0 -> 124127 bytes
-rw-r--r--yChat/ychat-0.7.1.tar.bz2bin0 -> 125087 bytes
-rw-r--r--yChat/ychat-0.7.2.tar.bz2bin0 -> 113640 bytes
-rw-r--r--yChat/ychat-0.7.3.tar.bz2bin0 -> 114017 bytes
-rw-r--r--yChat/ychat-0.7.4.1.tar.bz2bin0 -> 113726 bytes
-rw-r--r--yChat/ychat-0.7.5.tar.bz2bin0 -> 116694 bytes
-rw-r--r--yChat/ychat-0.7.6.tar.bz2bin0 -> 115702 bytes
-rw-r--r--yChat/ychat-0.7.7.0.tar.bz2bin0 -> 113976 bytes
-rw-r--r--yChat/ychat-0.7.7.1.tar.bz2bin0 -> 113780 bytes
-rw-r--r--yChat/ychat-0.7.8.tar.bz2bin0 -> 116917 bytes
-rw-r--r--yChat/ychat-0.7.9.0.tar.bz2bin0 -> 119470 bytes
-rw-r--r--yChat/ychat-0.7.9.1.tar.bz2bin0 -> 117002 bytes
-rw-r--r--yChat/ychat-0.7.9.2.tar.bz2bin0 -> 116239 bytes
-rw-r--r--yChat/ychat-0.7.9.3.tar.bz2bin0 -> 111797 bytes
-rw-r--r--yChat/ychat-0.7.9.4.tar.bz2bin0 -> 111917 bytes
-rw-r--r--yChat/ychat-0.7.9.5.tar.bz2bin0 -> 113717 bytes
-rw-r--r--yChat/ychat-0.8.0.tar.bz2bin0 -> 119501 bytes
-rw-r--r--yChat/ychat-0.8.1.tar.bz2bin0 -> 120381 bytes
-rw-r--r--yChat/ychat-0.8.2.tar.bz2bin0 -> 122336 bytes
-rw-r--r--yhttpd/IMPORTANT.txt1
-rw-r--r--yhttpd/THIS_IS_LEGACY_SOFTWARE_AND_MIGHT_BE_BROKEN.txt2
-rw-r--r--yhttpd/desc/BRANCH_0_71
-rw-r--r--yhttpd/desc/BRANCH_0_81
-rw-r--r--yhttpd/yhttpd-0.7.0.tar.bz2bin0 -> 192570 bytes
-rw-r--r--yhttpd/yhttpd-0.7.1.tar.bz2bin0 -> 194129 bytes
-rw-r--r--yhttpd/yhttpd-0.7.2.tar.bz2bin0 -> 70500 bytes
140 files changed, 4027 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..b3ada67
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,484 @@
+2003-09-14 16:55 snooper
+
+ * cmnd/yc_version.cpp: Added /version command.
+
+2003-09-14 16:48 snooper
+
+ * README, msgs.h: Changed Version to 0.5 ( Will be released as soon
+ as possible ).
+
+2003-09-14 16:34 snooper
+
+ * msgs.h: Changed version description.
+
+2003-09-14 16:31 snooper
+
+ * README, conf.txt, glob.h, reqp.cpp, sock.cpp, cmnd/compile.sh:
+ Fixed all known bugs which already have been fixed in yChat++
+ Advanced.
+
+2003-09-13 20:52 snooper
+
+ * gfx/y_ani_black.gif, gfx/y_ani_white.gif, html/favicon.ico: [no
+ log message]
+
+2003-09-07 14:49 snooper
+
+ * pool.cpp:
+ Removed a pthread_cond_signal which has been set twice!
+
+2003-09-06 23:34 rover
+
+ * pool.cpp: fixed a typo ( multi thread bug )
+
+2003-09-03 18:30 rover
+
+ * reqp.cpp: modified End-Of-Headers to RFC compliant version
+
+2003-07-26 14:30 snooper
+
+ * reqp.cpp: Added Pragma: no-cache and Expires: 0 to the HTTP
+ header. ( this is a bugfix ).
+
+2003-04-19 21:39 rover
+
+ * chat.cpp, reqp.cpp, sess.cpp, sess.h, sman.h, sock.cpp, user.h:
+ identification now only depends on session
+
+2003-04-19 18:16 rover
+
+ * Makefile.in, chat.cpp, chat.h, conf.txt, main.cpp, s_sman.cpp,
+ sess.cpp, sman.cpp, s_sman.h, sess.h, sman.h: added session
+ manager and session object.
+
+2003-04-10 17:36 rover
+
+ * logd.cpp: fixed a typo
+
+2003-04-07 15:24 rover
+
+ * hmap.cpp: added a really really important newline ( this is just
+ a loginfo test )
+
+2003-04-07 15:18 rover
+
+ * msgs.h: message templates are now replaced by language manager
+
+2003-04-05 00:17 rover
+
+ * Makefile.in: language support
+
+2003-04-05 00:14 rover
+
+ * chat.cpp, chat.h, conf.txt, lang.cpp, lang.h, main.cpp,
+ s_lang.cpp, s_lang.h, sock.cpp, user.cpp, user.h, lang/de,
+ lang/en: support for different languages in chat output
+
+2003-04-04 23:35 rover
+
+ * conf.cpp, conf.txt, glob.h, s_conf.h, sock.cpp: another bug that
+ was caused due sed conversion
+
+2003-04-04 17:42 rover
+
+ * Makefile.in: added log_daemon
+
+2003-04-04 17:19 rover
+
+ * conf.txt, logd.cpp, logd.h, reqp.cpp, reqp.h, sock.cpp, sock.h:
+ added access log compatible logging
+
+2003-04-04 13:13 rover
+
+ * sock.cpp: added IP / PORT to map_params to make logging possible
+ with only this map
+
+2003-04-04 12:41 rover
+
+ * s_tool.cpp, s_tool.h: added trim() function to strip whitespaces
+ at the beginning and end of a string
+
+2003-04-04 12:40 rover
+
+ * reqp.cpp, reqp.h: http headers are now stored in the requestmap
+
+2003-04-03 01:01 snooper
+
+ * s_modl.cpp, s_modl.h, user.h: Minor modifications. New static
+ class wrapper.
+
+2003-04-02 23:57 snooper
+
+ * Makefile.in, chat.h, conf.txt, main.cpp, modl.cpp, sock.cpp,
+ user.cpp, user.h, cmnd/yc_q.cpp: Added first command. /q ...
+ Todo: each user should have his own hashmap of executable
+ modules. Right now all users use the same module hash map.
+
+2003-04-02 15:23 rover
+
+ * modl.cpp, modl.h: module loader
+
+2003-04-02 12:52 snooper
+
+ * dltest.cpp, yc_test.cpp, cmnd/yc_q.cpp, cmnd/yc_test.cpp: [no log
+ message]
+
+2003-04-02 12:50 snooper
+
+ * Makefile.in, README, base.cpp, base.h, chat.cpp, chat.h,
+ conf.cpp, dltest.cpp, glob.h, hmap.cpp, hmap.h, html.cpp, msgs.h,
+ reqp.cpp, reqp.h, sock.cpp: Dynamic module loader class. Better
+ hash map functionality. Some bugfixes.
+
+2003-03-30 15:40 paul
+
+ * hmap.h:
+ Implementation of operator[].
+
+2003-03-30 13:12 volker
+
+ * html/: style.css, y_black.gif: added stylesheet and an image
+
+2003-03-30 03:48 paul
+
+ * todo.txt: [no log message]
+
+2003-03-30 03:35 paul
+
+ * base.cpp, conf.txt, hmap.cpp, hmap.h: The hach map now supports
+ explicit key bindings on each value. The [] operator still has to
+ be implemented.
+
+2003-03-30 01:34 volker
+
+ * conf.txt, html/index.html, html/input.html, html/online.html,
+ html/stream.html: modified appearance and added css
+
+2003-03-30 01:26 paul
+
+ * README, README.txt, cont.h: Renamed.
+
+2003-03-30 01:14 paul
+
+ * base.cpp, base.h, hmap.cpp, hmap.h: All user objects and all room
+ objects are stored in a hash map.
+
+2003-03-30 01:06 volker
+
+ * conf.txt, reqp.cpp, reqp.h, s_tool.cpp, s_tool.h: support for
+ different content-types
+
+2003-03-30 00:21 paul
+
+ * hmap.cpp, hmap.h, main.cpp: Now handles pointer of data objects
+ instead of references.
+
+2003-03-30 00:18 volker
+
+ * html.cpp: removed possible deadlock
+
+2003-03-30 00:11 volker
+
+ * conf.txt, html.cpp: changed format how files are read into
+ templatecache
+
+2003-03-28 17:16 volker
+
+ * todo.txt: todo is now up to date
+
+2003-03-28 03:51 paul
+
+ * data.h:
+
+ Removed data.h
+
+2003-03-28 03:51 paul
+
+ * README.txt, base.h, chat.h, data.h, room.h:
+
+ Put data.h and base.h together.
+
+2003-03-28 03:08 paul
+
+ * README.txt:
+
+ Actualizing because of the new configure script.
+
+2003-03-28 03:02 volker
+
+ * configure, configure.in: [no log message]
+
+2003-03-28 02:59 volker
+
+ * configure, configure.in: -ldl is not needed under *bsd. Added a
+ check
+
+2003-03-28 02:38 volker
+
+ * Makefile, Makefile.in, configure, configure.in: added support for
+ bsd
+
+2003-03-28 01:38 volker
+
+ * base.cpp: changed a bug in cvs keywords
+
+2003-03-28 01:32 volker
+
+ * base.cpp: [no log message]
+
+2003-03-28 01:27 volker
+
+ * COPYING, configure.in: this file should be in every repository ;)
+
+2003-03-28 01:18 volker
+
+ * Makefile, Makefile.in, configure, configure.in: configure
+ dependent files
+
+2003-03-28 00:22 paul
+
+ * hmap.cpp, hmap.h:
+
+ Optimization of the hash map.
+
+2003-03-27 17:14 volker
+
+ * dltest.cpp, yc_test.cpp: Dynamic module test
+
+2003-03-26 18:50 paul
+
+ * html/index.html:
+
+ Changed POST back to GET due read bug.
+
+2003-03-26 17:40 paul
+
+ * reqp.cpp:
+
+ Bugfix.
+
+2003-03-26 16:44 paul
+
+ * reqp.cpp, sock.cpp, sock.h:
+
+ Fixed segfault bug. ( stream.html request without existing user
+ object ).
+
+2003-03-26 16:17 paul
+
+ * sock.cpp:
+
+ Deletion of variables which are no longer needed after procession
+ ( e.g. map_params ).
+
+2003-03-26 15:57 paul
+
+ * thrd.cpp:
+
+ Bugfix. Now every socket connection will be closed the right way
+ ;).
+
+2003-03-26 00:03 paul
+
+ * chat.cpp, chat.h, sock.cpp:
+
+ Bugfix + added to the class chat a private bool b_strip_html
+ member.
+
+2003-03-25 23:52 paul
+
+ * chat.cpp:
+
+ Style fix.
+
+2003-03-25 23:41 paul
+
+ * msgs.h, sock.cpp:
+
+ Bugfix.
+
+2003-03-25 23:21 paul
+
+ * name.h:
+
+ Bugfix.
+
+2003-03-25 23:19 paul
+
+ * Makefile, README.txt, base.cpp, base.h, conf.txt, data.h,
+ hmap.cpp, hmap.h, name.cpp, name.h:
+
+ Changed because of hashmap integration. base.cpp and base.h still
+ have to be modified. Afterwards, all user and rooms will be
+ stored in a hash map.
+
+2003-03-25 21:06 paul
+
+ * Makefile, hmap.cpp, hmap.h, user.h:
+
+ Hash Map implementation.
+
+2003-03-25 20:12 volker
+
+ * chat.cpp, conf.txt, s_tool.cpp, s_tool.h: added possibility to
+ turn html tags on/off in chat messages
+
+2003-03-25 19:53 paul
+
+ * conf.txt, html.cpp:
+
+ Bugfix.
+
+2003-03-25 18:44 paul
+
+ * conf.txt:
+
+ Bugfix.
+
+2003-03-25 17:22 volker
+
+ * conf.txt, main.cpp: removed some typos that where created due to
+ sed conversation
+
+2003-03-25 15:54 volker
+
+ * CHAT.cpp, CHAT.h, CONF.cpp, CONF.h, HTML.cpp, HTML.h, MUTX.cpp,
+ MUTX.h, Makefile, README.txt, SOCK.cpp, SOCK.h, TOOL.cpp, TOOL.h,
+ chat.cpp, chat.h, cmnd.cpp, conf.cpp, conf.h, conf.txt, cont.cpp,
+ data.h, glob.h, html.cpp, html.h, main.cpp, msgs.h, mutx.cpp,
+ mutx.h, pool.cpp, reqp.cpp, s_chat.cpp, s_chat.h, s_conf.cpp,
+ s_conf.h, s_html.cpp, s_html.h, s_mutx.cpp, s_mutx.h, s_sock.cpp,
+ s_sock.h, s_tool.cpp, s_tool.h, sock.cpp, sock.h, thrd.cpp,
+ user.cpp: changed filenames to windows compatible ones
+
+2003-03-25 00:49 paul
+
+ * README.txt:
+
+ Bugfixes.
+
+2003-03-25 00:40 paul
+
+ * todo.txt:
+
+ New brainstorming.
+
+2003-03-25 00:16 paul
+
+ * TOOL.cpp, TOOL.h, chat.cpp, msgs.h:
+
+ Added check routine if a login nick is alphanumeric or not. If
+ not a message will appear on the startpage instead of logging in
+ which may would end in a segmentation fault.
+
+2003-03-24 23:45 paul
+
+ * main.cpp: [no log message]
+
+2003-03-24 23:43 paul
+
+ * README.txt, chat.cpp, msgs.h, user.cpp, user.h:
+
+ Added support for chat commands ( chat commands still have to be
+ implemented ). If you type "/testhere" ychat will tell that
+ there is no such command!
+
+2003-03-24 00:30 paul
+
+ * Makefile, cmnd.cpp, main.cpp, msgs.h, reqp.cpp, reqp.h, sock.cpp,
+ sock.h, thrd.cpp, user.cpp, user.h: [no log message]
+
+2003-03-23 23:34 vrichter
+
+ * reqp.cpp: removed bogus sock.h
+
+2003-03-23 23:29 vrichter
+
+ * reqp.cpp, sock.cpp: bugfix POST system
+
+2003-03-23 20:03 vrichter
+
+ * html/index.html: changed the method of the login form to POST
+
+2003-03-23 20:02 vrichter
+
+ * reqp.cpp, reqp.h: the request parser now supports POST
+
+2003-03-23 16:16 paul
+
+ * pool.cpp:
+
+ Fixed changing date! ( System clock was set wrong ),
+
+2003-03-23 16:05 paul
+
+ * pool.cpp: [no log message]
+
+2003-03-23 12:33 paul
+
+ * conf.txt, pool.cpp: [no log message]
+
+2003-03-23 06:41 paul
+
+ * base.cpp, chat.cpp, conf.cpp, cont.cpp, html.cpp, main.cpp,
+ mutx.cpp, name.cpp, reqp.cpp, room.cpp, thrd.cpp, user.cpp,
+ msgs.h: [no log message]
+
+2003-03-23 06:26 paul
+
+ * pool.cpp: [no log message]
+
+2003-03-23 05:55 paul
+
+ * Makefile, README.txt, conf.txt, glob.h, main.cpp, msgs.h,
+ pool.cpp, pool.h, reqp.h, sock.cpp, sock.h: [no log message]
+
+2003-03-22 23:07 paul
+
+ * README.txt: [no log message]
+
+2003-03-22 22:56 paul
+
+ * html.h: [no log message]
+
+2003-03-22 07:40 vrichter
+
+ * reqp.h: fixed a paste error
+ ----------------------------------------------------------------------
+
+2003-03-21 20:38 vrichter
+
+ * yc.tgz, ychat: removed binary files that were transfered
+
+2003-03-21 19:31 vrichter
+
+ * reqp.cpp, reqp.h, ychat: added url decoding
+
+2003-03-21 16:54 root
+
+ * CHAT.cpp, CHAT.h, CONF.cpp, CONF.h, HTML.cpp, HTML.h, MUTX.cpp,
+ MUTX.h, Makefile, README.txt, SOCK.cpp, SOCK.h, TOOL.cpp, TOOL.h,
+ base.cpp, base.h, chat.cpp, chat.h, cmnd.cpp, cmnd.h, conf.cpp,
+ conf.h, conf.txt, cont.cpp, cont.h, data.h, glob.h, html.cpp,
+ html.h, incl.h, main.cpp, msgs.h, mutx.cpp, mutx.h, name.cpp,
+ name.h, reqp.cpp, reqp.h, room.cpp, room.h, sock.cpp, sock.h,
+ thrd.cpp, thrd.h, todo.txt, user.cpp, user.h, yc.tgz, ychat,
+ gfx/y_ani_black.gif, gfx/y_ani_white.gif, html/blank.html,
+ html/frameset.html, html/index.html, html/input.html,
+ html/notfound.html, html/online.html, html/stream.html,
+ html/y_ani.gif: Initial revision
+
+2003-03-21 16:54 root
+
+ * CHAT.cpp, CHAT.h, CONF.cpp, CONF.h, HTML.cpp, HTML.h, MUTX.cpp,
+ MUTX.h, Makefile, README.txt, SOCK.cpp, SOCK.h, TOOL.cpp, TOOL.h,
+ base.cpp, base.h, chat.cpp, chat.h, cmnd.cpp, cmnd.h, conf.cpp,
+ conf.h, conf.txt, cont.cpp, cont.h, data.h, glob.h, html.cpp,
+ html.h, incl.h, main.cpp, msgs.h, mutx.cpp, mutx.h, name.cpp,
+ name.h, reqp.cpp, reqp.h, room.cpp, room.h, sock.cpp, sock.h,
+ thrd.cpp, thrd.h, todo.txt, user.cpp, user.h, yc.tgz, ychat,
+ gfx/y_ani_black.gif, gfx/y_ani_white.gif, html/blank.html,
+ html/frameset.html, html/index.html, html/input.html,
+ html/notfound.html, html/online.html, html/stream.html,
+ html/y_ani.gif: imported files into ychat cvs
+
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..300d035
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,12 @@
+SRCS=chat.cpp s_chat.cpp cmnd.cpp conf.cpp s_conf.cpp cont.cpp html.cpp s_html.cpp lang.cpp s_lang.cpp logd.cpp main.cpp modl.cpp s_modl.cpp mutx.cpp s_mutx.cpp name.cpp pool.cpp reqp.cpp room.cpp sock.cpp s_sock.cpp thrd.cpp s_tool.cpp user.cpp sess.cpp sman.cpp s_sman.cpp
+OBJS=$(SRCS:.cpp=.o)
+CC=g++
+LDFLAGS=@LDFLAGS@ -lstdc++ -g
+LDADD=-pthread -D_THREAD_SAFE
+all: ychat
+$(SRCS):
+ $(CC) $(CFLAGS) -c $*.cpp
+ychat: $(OBJS)
+ $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDADD)
+clean:
+ rm *.o
diff --git a/base.cpp b/base.cpp
new file mode 100644
index 0000000..c298ef7
--- /dev/null
+++ b/base.cpp
@@ -0,0 +1,65 @@
+/*
+ This file is part of yChat
+
+ $Author: cvs $
+ $Date: 2004-04-05 10:37:17 $
+
+ $Header: /cvs/cvsroot/ychat-0.5/base.cpp,v 1.1.1.1 2004-04-05 10:37:17 cvs Exp $
+*/
+// template class data implementation;
+
+#ifndef BASE_CPP
+#define BASE_CPP
+
+#include "base.h"
+
+template<class type>
+base<type>::base()
+{
+ map_elem = new hmap<type*,string>(80);
+ pthread_mutex_init (&mut_map_elem, NULL );
+}
+
+template<class type>
+base<type>::~base( )
+{
+ pthread_mutex_destroy( &mut_map_elem );
+}
+
+template<class type> void
+base<type>::add_elem( type* p_type )
+{
+ pthread_mutex_lock ( &mut_map_elem );
+ map_elem->add_elem ( p_type, p_type->get_name());
+ pthread_mutex_unlock( &mut_map_elem );
+}
+
+template<class type> void
+base<type>::del_elem( string &s_name )
+{
+ pthread_mutex_lock ( &mut_map_elem );
+ map_elem->del_elem ( s_name );
+ pthread_mutex_unlock( &mut_map_elem );
+}
+
+template<class type> type*
+base<type>::get_elem( string &s_name, bool &b_found )
+{
+ pthread_mutex_lock ( &mut_map_elem );
+ type* p_type = map_elem->get_elem( s_name );
+ pthread_mutex_unlock( &mut_map_elem );
+
+ b_found = p_type == NULL ? false : true;
+
+ return p_type;
+}
+
+template<class type> void
+base<type>::run_func( void (*func)(type*, void*), void* v_arg )
+{
+ pthread_mutex_lock ( &mut_map_elem );
+ map_elem->run_func( func, v_arg );
+ pthread_mutex_unlock( &mut_map_elem );
+}
+
+#endif
diff --git a/base.h b/base.h
new file mode 100644
index 0000000..6f06e4b
--- /dev/null
+++ b/base.h
@@ -0,0 +1,71 @@
+// template class data declaration;
+
+#ifndef BASE_H
+#define BASE_H
+
+#include "incl.h"
+#include "hmap.h"
+
+template<class type>
+class base
+{
+private:
+ hmap<type*,string>* map_elem;
+ pthread_mutex_t mut_map_elem;
+
+public:
+ base();
+ ~base();
+
+ virtual void add_elem( type* p_type ); // add a element.
+ virtual void del_elem( string &s_name ); // delete a alement.
+ virtual type* get_elem( string &s_name, bool &b_found ); // get a element.
+
+ // execute func on all elements of map_elem. v_pointer is the argument.
+ virtual void run_func( void (*func)(type*, void*), void* v_arg );
+
+ // chat::msg_post sends to all users of the system a message.
+ // room::msg_post sends to all users of the room a message.
+ // user::msg_post sends to the user a message.
+ void msg_post( string *s_msg )
+ {
+ run_func( &base<type>::msg_post_ , (void*)s_msg );
+ }
+ static void msg_post_( type* type_obj, void* v_arg )
+ {
+ string *p_msg = (string*) v_arg;
+ type_obj -> msg_post( p_msg );
+ }
+
+ void get_data( map_string *p_map_string )
+ {
+ run_func( &base<type>::get_data_ , (void*)p_map_string );
+ }
+ static void get_data_( type* type_obj, void* v_arg )
+ {
+ map_string *map_params = (map_string*) v_arg;
+ type_obj -> get_data ( map_params );
+ }
+
+ // chat::get_user_list gets a list of all users of the system.
+ // room::get_user_list gets a list of all users of the room.
+ // user::get_user_list gets a "list" of a user <font color="usercolor">username</font>seperator
+ void get_user_list( string &s_list, string &s_seperator )
+ {
+
+ container c;
+ c.elem[0] = (void*) &s_list;
+ c.elem[1] = (void*) &s_seperator;
+
+ run_func( &base<type>::get_user_list_, (void*)&c );
+ }
+ static void get_user_list_( type* type_obj, void* v_arg )
+ {
+ container *c = (container*) v_arg;
+ type_obj -> get_user_list( *((string*)c->elem[0]), *((string*)c->elem[1]) );
+ }
+};
+
+#include "base.cpp"
+
+#endif
diff --git a/chat.cpp b/chat.cpp
new file mode 100644
index 0000000..b845ec3
--- /dev/null
+++ b/chat.cpp
@@ -0,0 +1,147 @@
+// class chat implementation.
+
+#ifndef s_chat_CXX
+#define s_chat_CXX
+
+#include "chat.h"
+#include "s_conf.h"
+#include "s_mutx.h"
+#include "s_tool.h"
+
+using namespace std;
+
+chat::chat( )
+{
+ if ( s_conf::get().get_val( "HTML" ) == "OFF" )
+ b_strip_html = true;
+ else
+ b_strip_html = false;
+
+}
+
+chat::~chat( )
+{
+}
+
+user*
+chat::get_user( string &s_user )
+{
+ bool b_flag;
+ return get_user( s_user, b_flag );
+}
+
+user*
+chat::get_user( string &s_user, bool &b_found )
+{
+ container param;
+
+ param.elem[0] = (void*) &s_user ;
+ param.elem[1] = (void*) &b_found;
+
+ b_found = false;
+
+ run_func( get_user_, (void*)&param );
+
+ if ( *( (bool*)param.elem[1] ) )
+ return (user*)param.elem[2];
+}
+
+void
+chat::get_user_( room *room_obj, void *v_arg )
+{
+ container* param = (container*) v_arg;
+ param->elem[2] = (void*)room_obj->get_elem( *((string*)param->elem[0]), *((bool*)param->elem[1]) );
+}
+
+void
+chat::login( map_string &map_params )
+{
+ string s_user = map_params["nick"];
+
+ // prove if nick is empty:
+ if ( s_user.empty() )
+ {
+ map_params["INFO"] = E_NONICK;
+ map_params["request"] = s_conf::get().get_val( "STARTMPL" ); // redirect to the startpage.
+ return;
+ }
+
+ // prove if the nick ist alphanumeric:
+ else if ( ! s_tool::is_alpha_numeric( s_user ) )
+ {
+ map_params["INFO"] = E_ALPNUM;
+ map_params["request"] = s_conf::get().get_val( "STARTMPL" ); // redirect to the startpage.
+ return;
+ }
+
+ bool b_flag;
+
+ // prove if nick is already online / logged in.
+ get_user( s_user, b_flag );
+ if ( b_flag )
+ {
+ map_params["INFO"] = E_ONLINE;
+ map_params["request"] = s_conf::get().get_val( "STARTMPL" );
+ return;
+ }
+
+ string s_room = map_params["room"];
+ room* p_room = get_room( s_room , b_flag );
+
+ // if room does not exist add room to list!
+ if ( ! b_flag )
+ {
+ p_room = new room( s_room );
+
+#ifdef VERBOSE
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cout << NEWROOM << s_room << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+#endif
+
+ add_elem( p_room );
+ }
+
+ user *p_user = new user( s_user );
+
+ // add user to the room.
+ p_room->add_user( p_user );
+ sess *ns =s_sman::get().createSession();
+ ns->setValue(string("nick"), (void *)new string(s_user) );
+ map_params["tmpid"]=ns->getId();
+ // post "username enters the chat" into the room.
+ p_room->msg_post( new string( s_user.append( s_lang::get().get_val( "USERENTR" ) ) ) );
+
+#ifdef VERBOSE
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cout << LOGINPR << s_user << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+#endif
+}
+
+void
+chat::post( user* p_user, map_string &map_params )
+{
+
+ string s_msg( map_params["message"] );
+
+ auto unsigned i_pos = s_msg.find( "/" );
+ if ( i_pos == 0 )
+ return p_user->command( s_msg );
+
+ if ( b_strip_html )
+ s_tool::strip_html( &s_msg );
+
+ string s_post( "<font color=\"" );
+
+ s_post.append( p_user->get_col1() )
+ .append( "\">" )
+ .append( p_user->get_name() )
+ .append( ": " )
+ .append( s_msg )
+ .append( "</font><br>\n" );
+
+ p_user->get_p_room()->msg_post( &s_post );
+}
+
+#endif
diff --git a/chat.h b/chat.h
new file mode 100644
index 0000000..60bcf9d
--- /dev/null
+++ b/chat.h
@@ -0,0 +1,46 @@
+// class chat declaration.
+
+#ifndef s_chat_H
+#define s_chat_H
+
+#include <vector>
+#include "incl.h"
+#include "base.h"
+#include "room.h"
+#include "user.h"
+#include "sess.h"
+#include "s_lang.h"
+#include "s_sman.h"
+
+using namespace std;
+
+class chat : public base<room>
+{
+private:
+ bool b_strip_html;
+
+public:
+
+
+ room* get_room( string &s_name, bool &b_found )
+ {
+ return static_cast<room*>( get_elem( s_name, b_found ) );
+ }
+
+ // public methods:
+ explicit chat(); // a standard constructor.
+ ~chat(); // destructor.
+
+ // get the object of a specific user.
+ virtual user* get_user( string &s_nick );
+ virtual user* get_user( string &s_nick, bool &b_found );
+ static void get_user_( room* room_obj, void *v_arg );
+
+ // will be called every time a user tries to login.
+ virtual void login( map_string &map_params );
+
+ // will be called if a user posts a message.
+ virtual void post ( user* u_user, map_string &map_params );
+};
+
+#endif
diff --git a/cmnd.cpp b/cmnd.cpp
new file mode 100644
index 0000000..28e73a7
--- /dev/null
+++ b/cmnd.cpp
@@ -0,0 +1,19 @@
+// class cmnd implementation.
+
+#ifndef CMND_CXX
+#define CMND_CXX
+
+#include "cmnd.h"
+#include "s_mutx.h"
+
+using namespace std;
+
+cmnd::cmnd( )
+{
+}
+
+cmnd::~cmnd()
+{
+}
+
+#endif
diff --git a/cmnd.h b/cmnd.h
new file mode 100644
index 0000000..2eb1db2
--- /dev/null
+++ b/cmnd.h
@@ -0,0 +1,18 @@
+// class cmnd declaration.
+
+#ifndef CMND_H
+#define CMND_H
+
+#include "incl.h"
+
+using namespace std;
+
+class cmnd
+{
+public:
+ // public methods:
+ explicit cmnd( ); // a standard constructor.
+ ~cmnd( );
+};
+
+#endif
diff --git a/conf.cpp b/conf.cpp
new file mode 100644
index 0000000..3ff71b8
--- /dev/null
+++ b/conf.cpp
@@ -0,0 +1,75 @@
+// class conf implementation.
+
+#ifndef s_conf_CXX
+#define s_conf_CXX
+
+#include <fstream>
+#include "conf.h"
+
+using namespace std;
+
+conf::conf( string s_conf = CONFILE ) : name( s_conf )
+{
+ parse( ); // parse the config file.
+}
+
+conf::~conf()
+{
+}
+
+void
+conf::parse()
+{
+#ifdef VERBOSE
+ cout << CFILEOK << get_name() << endl;
+#endif
+
+ ifstream fs_conf( get_name().c_str() );
+
+ if ( ! fs_conf )
+ {
+#ifdef VERBOSE
+ cout << CFILENO << get_name() << endl;
+#endif
+ return;
+ }
+
+ char c_buf[READBUF];
+
+ while( fs_conf.getline( c_buf, READBUF ) )
+ {
+ string s_token( c_buf );
+ unsigned int ui_pos = s_token.find( "#", 0 );
+
+ // if line is commented out:
+ if ( ui_pos == 0 )
+ continue;
+
+ ui_pos = s_token.find( ";", 0 );
+
+ // if token has not been found.
+ if ( ui_pos == string::npos )
+ continue;
+
+ s_token = s_token.substr( 0 , --ui_pos );
+ ui_pos = s_token.find ( "\"", 0 );
+
+ if ( ui_pos == string::npos )
+ continue;
+
+ string s_val = s_token.substr( ui_pos+1, s_token.length() );
+ string s_key = s_token.substr( 0 , --ui_pos );
+
+#ifdef VERBOSE2
+ cout << s_key << "=" << s_val << endl;
+#endif
+
+ // fill the map.
+ map_vals[s_key] = s_val;
+ }
+
+ fs_conf.close();
+ fs_conf.~ifstream();
+}
+
+#endif
diff --git a/conf.h b/conf.h
new file mode 100644
index 0000000..6e2a890
--- /dev/null
+++ b/conf.h
@@ -0,0 +1,24 @@
+// class conf declaration. this class parses the server config file.
+
+#ifndef s_conf_H
+#define s_conf_H
+
+#include "incl.h"
+#include "cont.h"
+#include "name.h"
+
+using namespace std;
+
+class conf : public cont, name
+{
+private:
+
+public:
+ // public methods:
+ conf ( string s_conf ); // standard constructor.
+ ~conf(); // standard destructor.
+
+ virtual void parse( ); // parses the config file.
+};
+
+#endif
diff --git a/configure.in b/configure.in
new file mode 100644
index 0000000..7512df7
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,28 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(s_chat.h)
+#AC_INIT_AUTOMAKE(yChat, 0.2)
+dnl Checks for programs.
+
+AC_CYGWIN
+AC_MINGW32
+AC_PROG_CPP
+AC_PROG_CXX
+
+dnl Checks for libraries.
+dnl Replace `main' with a function in -lstdc:
+AC_SEARCH_LIBS(dlopen, dl)
+if test "$ac_cv_search_dlopen" = "-ldl"; then
+LDFLAGS="$ac_cv_search_dlopen"
+fi
+dnl Checks for header files.
+AC_HEADER_DIRENT
+AC_HEADER_STDC
+AC_CHECK_HEADERS(unistd.h)
+AC_CHECK_HEADERS(string.h)
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_C_INLINE
+
+dnl Checks for library functions.
+
+AC_OUTPUT(Makefile)
diff --git a/cont.cpp b/cont.cpp
new file mode 100644
index 0000000..a437543
--- /dev/null
+++ b/cont.cpp
@@ -0,0 +1,24 @@
+// class cont implementation.
+
+#ifndef CONT_CXX
+#define CONT_CXX
+
+#include "cont.h"
+#include "s_mutx.h"
+
+using namespace std;
+
+string
+cont::get_val( string s_key )
+{
+ if ( map_vals.find( s_key ) != map_vals.end() )
+ return map_vals[ s_key ];
+ return string();
+}
+
+cont::~cont()
+{
+ map_vals.~map_string();
+}
+
+#endif
diff --git a/cont.h b/cont.h
new file mode 100644
index 0000000..90cbd7b
--- /dev/null
+++ b/cont.h
@@ -0,0 +1,26 @@
+// class cont declaration. defines a simple data container class.
+
+#ifndef CONT_H
+#define CONT_H
+
+#include "incl.h"
+#include "hmap.h"
+
+using namespace std;
+
+class cont
+{
+protected:
+ map_string map_vals;
+
+public:
+ cont::~cont();
+
+ // small inline methods:
+ void clear_vals() { map_vals.clear(); } // removes all values.
+
+ // public methods:
+ virtual string get_val( string s_key ); // get a specific map_vals value.
+};
+
+#endif
diff --git a/glob.h b/glob.h
new file mode 100644
index 0000000..6f89ef1
--- /dev/null
+++ b/glob.h
@@ -0,0 +1,68 @@
+// global variables.
+
+#ifndef GLOB_H
+#define GLOB_H
+
+#include <map>
+#include <pthread.h>
+
+// definition of boolean values.
+#define true 1
+#define false 0
+
+// config filename.
+#define CONFILE "conf.txt"
+
+// the highest port which is allowed to use. if ychat is unable to create the server
+// socket it will increment the port number and tries to create another socket.
+// this procedure will go on until MAXPORT is reached.
+#define MAXPORT 65535
+
+// max length of a line read from a socket or a file ( config-file, html-template ).
+#define READBUF 1024
+
+// definition for verbosity level 0 ( normal outputs ). see vmsg.h for custumizing all
+// the messages. this messages will only printed out by the master thread.
+#define VERBOSE
+
+// Defines the amount of newlines which have to send to the client's
+// chat stream the first log-in. ( prevents white screen because of buffers
+// or proxies ).
+#define PUSHSTR 1000
+
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// DO NOT CHANGE ANYTHING BEHIND THIS LINE!
+//////////////////////////////////////////////////////////////////////////////////////////
+
+using namespace std;
+
+// internal rang descriptors ( their external names may be specified different )
+enum rang
+{
+ CODER , // programmer.
+ ADMIN , // administrator.
+ MAGIC , // super user with special privileges.
+ SUPER , // temporary super user.
+ BASIC , // normal user without special privileges.
+ GUEST , // guest user, has almost no privileges.
+ RESTR , // a very restrivted user.
+ OUTBN // banned out of the system.
+};
+
+// some custom typedefs for datatypes which are needed often.
+typedef map<string, string> map_string;
+typedef int function( void *v_arg );
+
+struct container
+{
+ void* elem[3];
+};
+
+struct dynmod
+{
+ function *the_func ;
+ void *the_module;
+};
+
+#endif
diff --git a/hmap.cpp b/hmap.cpp
new file mode 100644
index 0000000..662a203
--- /dev/null
+++ b/hmap.cpp
@@ -0,0 +1,180 @@
+#ifndef hmap_cpp
+#define hmap_cpp
+
+
+#include "hmap.h"
+
+using namespace std;
+
+bool isPrime( int n );
+int nextPrime( int n );
+
+// Construct the hash table.
+template <class obj_type, class key_type>
+hmap<obj_type, key_type>::hmap( double mop )
+ : maxOccupiedPercentage(mop), array( nextPrime( 101 ) )
+{
+ cout << "hmap Constructor" << endl;
+ lookups = 0;
+ make_empty( );
+}
+
+// Insert item x into the hash table. If the item is
+// already present, do nothing
+template <class obj_type, class key_type>
+void hmap<obj_type, key_type>::add_elem( const obj_type &x, const key_type &k )
+{
+ // Insert x as active
+ int currentPos = findPos( k );
+ if( isActive( currentPos ) )
+ return;
+
+ array[ currentPos ] = hash_entry( x, k, ACTIVE );
+ // cout << "Inserted=" << x << "= at " << currentPos << endl;
+ if( ++occupied > array.size( ) * maxOccupiedPercentage )
+ rehash( );
+}
+
+// Expand the hash table.
+template <class obj_type, class key_type>
+void hmap<obj_type, key_type>::rehash( )
+{
+ vector<hash_entry> oldArray = array;
+
+ // Create new double-sized, empty table
+ array.resize( nextPrime( 2 * oldArray.size( ) ) );
+ for( int j = 0; j < array.size( ); j++ )
+ array[ j ].info = EMPTY;
+
+ // Copy table over
+ make_empty( );
+ for( int i = 0; i < oldArray.size( ); i++ )
+ if( oldArray[ i ].info == ACTIVE )
+ add_elem( oldArray[ i ].element, oldArray[ i ].key );
+}
+
+// Hash function, can only handle strings.
+// If you want to hash other objects you will have to
+// create a hash table for them
+template <class obj_type, class key_type>
+unsigned int hmap<obj_type, key_type>::hash( const string & key ) const
+{
+ unsigned int hashVal = 0;
+ // cout << key << "%";
+
+ for( size_t i = 0; i < key.size(); i++ )
+ hashVal = ( hashVal << 5 ) ^ key[ i ] ^ hashVal;
+
+ return hashVal;
+}
+
+// Method that performs quadratic probing resolution.
+// Return the position where the search for x terminates.
+template <class obj_type, class key_type>
+int hmap<obj_type, key_type>::findPos( const key_type &k )
+{
+ int collisionNum = 0;
+ int currentPos = hash( k ) % array.size( );
+ lookups++;
+
+ while( array[ currentPos ].info != EMPTY &&
+ array[ currentPos ].key != k )
+ {
+ // cout << array[ currentPos ].element << "!=" << x << endl;
+ lookups++;
+ currentPos += 2 * ++collisionNum - 1; // Compute ith probe
+
+ if( currentPos >= array.size( ) )
+ currentPos -= array.size( );
+ }
+
+ // cout << currentPos << " ";
+ return currentPos;
+}
+
+// Remove item x from the hash table.
+template <class obj_type, class key_type>
+void hmap<obj_type, key_type>::del_elem( const key_type & k )
+{
+ int currentPos = findPos( k );
+ if( isActive( currentPos ) )
+ array[ currentPos ].info = DELETED;
+}
+
+// Find item x in the hash table.
+// Return a pointer to the matching item or 0 if not found
+template <class obj_type, class key_type>
+obj_type hmap<obj_type, key_type>::get_elem( const key_type &k )
+{
+ int currentPos = findPos( k );
+ if( isActive( currentPos ) )
+ return array[ currentPos ].element;
+ else
+ return 0;
+}
+
+// Make the hash table logically empty.
+template <class obj_type, class key_type>
+void hmap<obj_type, key_type>::make_empty( )
+{
+ occupied = 0;
+ for( int i = 0; i < array.size( ); i++ )
+ array[ i ].info = EMPTY;
+}
+
+// Return true if currentPos exists and is active.
+template <class obj_type, class key_type>
+bool hmap<obj_type, key_type>::isActive( int currentPos ) const
+{
+ return array[ currentPos ].info == ACTIVE;
+}
+
+
+// Internal method to test if a positive number is prime.
+// Not an efficient algorithm.
+template <class obj_type, class key_type>
+bool hmap<obj_type, key_type>::isPrime( int n ) const
+{
+ if( n == 2 || n == 3 )
+ return true;
+
+ else if( n == 1 || n % 2 == 0 )
+ return false;
+
+ for( int i = 3; i * i <= n; i += 2 )
+ if( n % i == 0 )
+ return false;
+
+ return true;
+}
+
+// Internal method to return a prime number at least as large as n.
+// Assumes n > 0.
+template <class obj_type, class key_type>
+int hmap<obj_type, key_type>::nextPrime( int n ) const
+{
+ if( n % 2 == 0 )
+ n++;
+
+ for( ; !isPrime( n ); n += 2 );
+
+ return n;
+}
+template<class obj_type, class key_type> void
+hmap<obj_type, key_type>::run_func( void (*func)(obj_type) )
+{
+ for( int i = 0; i < array.size( ); i++ )
+ if ( array[i].info == ACTIVE )
+ ( *func ) ( array[i].element );
+}
+
+template<class obj_type, class key_type> void
+hmap<obj_type, key_type>::run_func( void (*func)(obj_type, void*), void* v_arg )
+{
+ for( int i = 0; i < array.size( ); i++ )
+ if ( array[i].info == ACTIVE )
+ ( *func ) ( array[i].element, v_arg );
+}
+
+#endif
+
diff --git a/hmap.h b/hmap.h
new file mode 100644
index 0000000..2392133
--- /dev/null
+++ b/hmap.h
@@ -0,0 +1,118 @@
+#pragma warning(disable:4786)
+
+#ifndef hmap_h
+#define hmap_h
+
+#include <vector>
+#include "incl.h"
+
+using namespace std;
+
+// void add_elem( obj_type x, key_type k ) --> Insert x
+// void del_elem( key_type k ) --> Remove x
+// obj_type get_elem( key_type k ) --> Return item that matches x
+// void make_empty( ) --> Remove all items
+
+template <class obj_type, class key_type>
+class hmap
+{
+private:
+ enum entry_type
+ {
+ ACTIVE, EMPTY, DELETED
+ };
+
+ struct hash_entry
+ {
+ obj_type element;
+ key_type key;
+ entry_type info;
+
+ hash_entry( const obj_type &e = obj_type( ), const key_type &k = key_type( ), entry_type i = EMPTY ) : element( e ), key( k ), info( i ) { }
+ };
+
+ int occupied;
+
+ virtual bool isActive( int currentPos ) const;
+ virtual void rehash( );
+ virtual bool isPrime ( int n ) const;
+ virtual int nextPrime( int n ) const;
+ double maxOccupiedPercentage;
+
+protected:
+ int lookups;
+ unsigned int hash( const string &key ) const;
+ vector<hash_entry> array;
+
+public:
+ hmap( double moc );
+
+ virtual int findPos ( const key_type &k );
+ virtual void make_empty( );
+ virtual void add_elem ( const obj_type &x, const key_type &k );
+ virtual void del_elem ( const key_type &k );
+ virtual obj_type get_elem ( const key_type &k );
+
+ virtual void run_func( void (*func)(obj_type) );
+ virtual void run_func( void (*func)(obj_type, void*), void* v_arg );
+
+ // inline:
+ void getSize()
+ {
+ int size = 0;
+ for( int j = 0; j < array.size( ); j++ )
+ if (array[ j ].info == ACTIVE)
+ size++;
+ return size;
+ };
+
+ int getLookups()
+ {
+ return lookups;
+ };
+
+ int getCapacity()
+ {
+ return array.size();
+ };
+
+ double getLambda()
+ {
+ return static_cast<double>(getSize())/static_cast<double>(getCapacity());
+ }
+
+ obj_type& operator[]( key_type &k )
+ {
+ return get_elem( k );
+ }
+
+};
+
+template <class obj_type, class key_type>
+class linearhmap : public hmap<obj_type, key_type> {
+public:
+ linearhmap(double moc) : hmap<obj_type, key_type>(moc) {};
+
+ virtual int findPos( const key_type &k )
+ {
+ int collisionNum = 0;
+ int currentPos = hash( k ) % array.size( );
+ lookups++;
+
+ while( array[ currentPos ].info != EMPTY &&
+ array[ currentPos ].key != k )
+ {
+ lookups ++;
+ currentPos++;
+
+ if( currentPos >= array.size( ) )
+ currentPos -= array.size( );
+ }
+
+ return currentPos;
+ }
+};
+
+#include "hmap.cpp"
+
+#endif
diff --git a/html.cpp b/html.cpp
new file mode 100644
index 0000000..f40e466
--- /dev/null
+++ b/html.cpp
@@ -0,0 +1,140 @@
+// class html implementation.
+
+#ifndef s_html_CXX
+#define s_html_CXX
+
+#include <fstream>
+#include "html.h"
+#include "s_chat.h"
+#include "s_mutx.h"
+
+using namespace std;
+
+html::html( )
+{
+ set_name( s_conf::get().get_val( "HTMLTEMP" ) );
+ pthread_mutex_init( &mut_map_vals, NULL );
+}
+
+html::~html( )
+{
+ pthread_mutex_destroy( &mut_map_vals );
+}
+
+void
+html::clear_cache( )
+{
+ pthread_mutex_lock ( &mut_map_vals );
+ clear_vals();
+ pthread_mutex_unlock( &mut_map_vals );
+}
+
+string
+html::parse( map_string &map_params )
+{
+ string s_file = map_params["request"];
+
+ // check if s_file is in the container.
+ pthread_mutex_lock ( &mut_map_vals );
+ string s_templ = get_val( s_file );
+ pthread_mutex_unlock( &mut_map_vals );
+
+ // if not, read file.
+ if ( s_templ.empty() )
+ {
+ auto string s_path = get_name();
+ auto ifstream fs_templ( s_path.append( s_file ).c_str(), ios::binary );
+
+ if ( ! fs_templ )
+ {
+
+ cerr << "File not found: " << s_file << endl;
+ if(map_params["request"]==s_conf::get().get_val( "NOTFOUND" ))
+ return "";
+
+ map_params["request"] = s_conf::get().get_val( "NOTFOUND" );
+ return parse( map_params );
+
+ }
+
+ auto char c_buf;
+ while( !fs_templ.eof() )
+ {
+ fs_templ.get( c_buf );
+ s_templ+=c_buf;
+ }
+
+ fs_templ.close();
+
+#ifdef VERBOSE
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cout << TECACHE << s_path << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+#endif
+
+ // cache file.
+ pthread_mutex_lock ( &mut_map_vals );
+ map_vals[ s_file ] = s_templ;
+ pthread_mutex_unlock( &mut_map_vals );
+ }
+
+ // find %%KEY%% token and substituate those.
+ auto unsigned int pos[2];
+ pos[0] = pos[1] = 0;
+
+ do
+ {
+ pos[0] = s_templ.find( "%%", pos[1] );
+
+ if ( pos[0] == string::npos )
+ break;
+
+ pos[0] += 2;
+ pos[1] = s_templ.find( "%%", pos[0] );
+
+ if ( pos[0] == string::npos )
+ break;
+
+ // get key and val.
+ auto string s_key = s_templ.substr( pos[0], pos[1]-pos[0] );
+ auto string s_val = s_conf::get().get_val( s_key );
+
+ // if s_val is empty use map_params.
+ if ( s_val.empty() )
+ s_val = map_params[ s_key ];
+
+ // substituate key with val.
+ s_templ.replace( pos[0]-2, pos[1]-pos[0]+4, s_val );
+
+ // calculate the string displacement.
+ auto int i_dif = s_val.length() - ( pos[1] - pos[0] + 4);
+
+ pos[1] += 2 + i_dif;
+
+ }
+ while( true );
+
+ return s_templ;
+}
+
+void
+html::online_list( user *p_user, map_string &map_params )
+{
+ // prepare user_list.
+ string s_list ( "" );
+ string s_seperator( "<br>" );
+
+ p_user->get_p_room()->get_user_list( s_list, s_seperator );
+
+ // use the collected data as a message in html-templates.
+ map_params["MESSAGE"] = s_list;
+
+ // renew the timestamp.
+ p_user->renew_stamp();
+
+ // send a ping to the client chat stream.
+ p_user->msg_post( new string("\n") );
+}
+
+#endif
+
diff --git a/html.h b/html.h
new file mode 100644
index 0000000..b43f0d2
--- /dev/null
+++ b/html.h
@@ -0,0 +1,42 @@
+// class html declaration. this class manages the html-template files.
+
+#ifndef s_html_H
+#define s_html_H
+
+#include "incl.h"
+#include "cont.h"
+#include "s_conf.h"
+#include "user.h"
+#include "name.h"
+
+
+using namespace std;
+
+class html : public cont, name
+{
+private:
+// needed for synchronizing the map_vals.
+ pthread_mutex_t mut_map_vals;
+
+public:
+ // public methods.
+ explicit html( ); // simple constructor.
+ ~html( );
+
+ // clears the template cache so that new html templates will be read
+ // from hard disk. this method is needed after changeing s.t. on
+ // the html-template files.
+ void clear_cache( );
+
+ // returns a parsed html-template. this method will check first if the
+ // required html-template exists inside the classes template cache. if not
+ // then the file will be read from file and added to the cache.
+ // afterwards the html-template will be parsed and returned.
+ // map_params contains the client request parameters which also will be
+ // used for string substituation.
+ virtual string parse( map_string &map_params );
+
+ virtual void online_list( user *p_user, map_string &map_params );
+};
+
+#endif
diff --git a/html/y_ani.gif b/html/y_ani.gif
new file mode 100644
index 0000000..e730988
--- /dev/null
+++ b/html/y_ani.gif
Binary files differ
diff --git a/incl.h b/incl.h
new file mode 100644
index 0000000..f8e483f
--- /dev/null
+++ b/incl.h
@@ -0,0 +1,16 @@
+// contains header files which are included by all classes.
+
+// include some std headers.
+#include <iostream>
+
+// since thread synchronization is a big issue this header needs
+// to be included by every other file too.
+#include <pthread.h>
+
+// std::string.
+#include <string>
+
+// include all the custom global variables.
+#include "glob.h"
+// include all the custom messages.
+#include "msgs.h"
diff --git a/lang.cpp b/lang.cpp
new file mode 100644
index 0000000..b5b33ec
--- /dev/null
+++ b/lang.cpp
@@ -0,0 +1,78 @@
+// class conf implementation.
+
+#ifndef s_lang_CXX
+#define s_lang_CXX
+
+#include <fstream>
+#include "lang.h"
+
+using namespace std;
+
+lang::lang( string s_lang = "en" ) : name( s_lang )
+{
+ parse( ); // parse the config file.
+}
+
+lang::~lang()
+{
+}
+
+void
+lang::parse()
+{
+#ifdef VERBOSE
+ cout << CFILEOK << get_name() << endl;
+#endif
+
+ string filename("lang/");
+ filename.append(get_name());
+
+ ifstream fs_conf( filename.c_str() );
+
+ if ( ! fs_conf )
+ {
+#ifdef VERBOSE
+ cout << CFILENO << get_name() << endl;
+#endif
+ return;
+ }
+
+ char c_buf[READBUF];
+
+ while( fs_conf.getline( c_buf, READBUF ) )
+ {
+ string s_token( c_buf );
+ unsigned int ui_pos = s_token.find( "#", 0 );
+
+ // if line is commented out:
+ if ( ui_pos == 0 )
+ continue;
+
+ ui_pos = s_token.find( ";", 0 );
+
+ // if token has not been found.
+ if ( ui_pos == string::npos )
+ continue;
+
+ s_token = s_token.substr( 0 , --ui_pos );
+ ui_pos = s_token.find ( "\"", 0 );
+
+ if ( ui_pos == string::npos )
+ continue;
+
+ string s_val = s_token.substr( ui_pos+1, s_token.length() );
+ string s_key = s_token.substr( 0 , --ui_pos );
+
+#ifdef VERBOSE2
+ cout << s_key << "=" << s_val << endl;
+#endif
+
+ // fill the map.
+ map_vals[s_key] = s_val;
+ }
+
+ fs_conf.close();
+ fs_conf.~ifstream();
+}
+
+#endif
diff --git a/lang.h b/lang.h
new file mode 100644
index 0000000..6745a93
--- /dev/null
+++ b/lang.h
@@ -0,0 +1,24 @@
+// class conf declaration. this class parses the server config file.
+
+#ifndef s_lang_H
+#define s_lang_H
+
+#include "incl.h"
+#include "cont.h"
+#include "name.h"
+
+using namespace std;
+
+class lang : public cont, name
+{
+private:
+
+public:
+ // public methods:
+ lang ( string s_lang ); // standard constructor.
+ ~lang(); // standard destructor.
+
+ virtual void parse( ); // parses the config file.
+};
+
+#endif
diff --git a/logd.cpp b/logd.cpp
new file mode 100644
index 0000000..cfdc7c6
--- /dev/null
+++ b/logd.cpp
@@ -0,0 +1,65 @@
+#ifndef LOGD_CXX
+#define LOGD_CXX
+
+#include "logd.h"
+
+logd::logd( string filename )
+{
+ if(filename.empty())
+ {
+ cerr << "ycLog: No filename specified" << endl;
+ exit(1);
+ }
+
+ s_logfile=filename;
+
+ i_lines=s_tool::string2int( s_conf::get().get_val("LOG_LINES"));
+
+}
+void logd::flush()
+{
+ s_output.open(s_logfile.c_str(), ios::app);
+
+ if(s_output==NULL)
+ {
+ cerr << "ycLog: Could not open file: " << s_logfile << endl;
+ exit(1);
+ }
+
+
+ while(!s_queue.empty())
+ {
+ string s_l=s_queue.front();
+ s_queue.pop();
+ s_output.write(s_l.c_str(), s_l.size());
+
+ }
+ s_output.close();
+}
+void logd::log( map_string request )
+{
+ struct tm *t_m;
+ time_t t_cur=time(NULL);
+ t_m=gmtime(&t_cur);
+
+ char buffer[100];
+ strftime(buffer, 100, "[%d/%b/%Y:%H:%M:%S %z]", t_m);
+ string s_time=buffer;
+ string s_logstr = request["REMOTE_ADDR"] + " - - "+s_time+" \"" + request["QUERY_STRING"]+"\" 200 0 \""+request["request"]+"\" \""+request["User-Agent"]+"\"\n";
+
+ s_queue.push(s_logstr);
+
+ if(s_queue.size()>=i_lines)
+ flush();
+}
+
+logd::~logd()
+{
+ flush();
+}
+
+
+
+
+
+#endif
diff --git a/logd.h b/logd.h
new file mode 100644
index 0000000..5d79d9d
--- /dev/null
+++ b/logd.h
@@ -0,0 +1,24 @@
+#ifndef LOGD_H
+#define LOGD_H
+
+#include "incl.h"
+#include "s_tool.h"
+#include "s_conf.h"
+#include <fstream>
+#include <queue>
+#include <time.h>
+class logd {
+
+ private:
+ string s_logfile;
+ queue<string> s_queue;
+ ofstream s_output;
+ int i_lines;
+ public:
+ logd( string filename );
+ ~logd();
+
+ void flush();
+ void log( map_string request );
+};
+#endif
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..08f89f8
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,98 @@
+/*
+ * yChat++; Contact: www.yChat.org; Mail@yChat.org
+ * Copyright (C) 2003 Paul C. Buetow, Volker Richter
+ * -----------------------------------------------------------------
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+// needed for ignoring SIGPIPE.
+#include <signal.h>
+
+// include header files which are included from every class too.
+#include "incl.h"
+
+// include the chat manager.
+#include "s_chat.h"
+
+// include the config manager.
+#include "s_conf.h"
+
+// include the html-template manager.
+#include "s_html.h"
+
+// include the mutex manager for global synchronization.
+#include "s_mutx.h"
+
+// include the module loader manager for global synchronization.
+#include "s_modl.h"
+
+// include the socket manager.
+#include "s_sock.h"
+
+// include the language manager
+#include "s_lang.h"
+
+// include the session manager
+#include "s_sman.h"
+
+using namespace std;
+
+int main()
+{
+#ifdef VERBOSE
+
+cout << " ___ _ _ " << endl
+ << " _ _ / __\\ |__ __ _| |_ " << endl
+ << "| | | |/ / | '_ \\ / _` | __|" << endl
+ << "| |_| / /___| | | | (_| | |_ " << endl
+ << " \\__, \\____/|_| |_|\\__,_|\\__|" << endl
+ << " |___/ " << endl << endl
+
+ << DESCRIP << endl
+ << VERSION << ", "
+ << CONTACT << endl
+ << SEPERAT << endl
+ << STARTMS << endl ;
+#endif
+
+ // ignore SIGPIPE. otherwise the server will shut down with "Broken pipe" if
+ // a client unexpected disconnects himself from a SOCK_STREAM.
+ signal( SIGPIPE, SIG_IGN );
+
+ // all the static data classes have to be initialized once. otherwise they will
+ // contain only empty pointers and the chat server won't work correctly.
+ // the order of the initializations is very importand. for example the s_html::init()
+ // invokations assumes an initialized s_conf class.
+ s_mutx::init(); // init the mutex manager.
+ s_conf::init(); // init the config manager.
+ s_html::init(); // init the html-template manager.
+ s_lang::init(); // init the language manager
+ s_sman::init(); // init the session manager.
+ s_modl::init(); // init the module-loader manager.
+ s_sock::init(); // init the socket manager.
+ s_chat::init(); // init the chat manager.
+
+ // start the socket manager. this one will listen for incoming http requests and will
+ // forward them to the specified routines which will generate a http response.
+ s_sock::get().start();
+
+#ifdef VERBOSE
+ cout << DOWNMSG << endl;
+#endif
+
+ return 0;
+}
diff --git a/modl.cpp b/modl.cpp
new file mode 100644
index 0000000..17c7b49
--- /dev/null
+++ b/modl.cpp
@@ -0,0 +1,98 @@
+// class modl implementation.
+
+#ifndef MODL_CXX
+#define MODL_CXX
+
+#include <limits.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <stdio.h>
+
+#include "s_mutx.h"
+#include "modl.h"
+
+using namespace std;
+
+modl::modl( )
+{
+ map_mods = new hmap<dynmod*,string>(80);
+ pthread_mutex_init( &mut_map_mods, NULL );
+}
+
+modl::~modl()
+{
+ pthread_mutex_lock ( &mut_map_mods );
+
+ // dlclose all the_module's first!
+ map_mods->run_func ( &modl::dlclose_ );
+
+ // then clean the hash map.
+ map_mods->make_empty ( );
+
+ pthread_mutex_unlock ( &mut_map_mods );
+ pthread_mutex_destroy( &mut_map_mods );
+}
+
+void
+modl::dlclose_( dynmod* mod )
+{
+ dlclose( mod->the_module );
+}
+
+dynmod*
+modl::cache_module( string s_name )
+{
+ void *the_module = NULL;
+ function *the_func = NULL;
+
+ the_module = dlopen( s_name.c_str(), RTLD_NOW );
+
+ if ( the_module == NULL )
+ {
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cerr << "dlerror: " << dlerror() << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+ return NULL;
+ }
+
+ the_func = (function*) dlsym( the_module, "extern_function" );
+
+ if ( the_func == NULL )
+ {
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cerr << "dlerror: " << dlerror() << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+ return NULL;
+ }
+
+#ifdef VERBOSE
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cout << MODULEC << s_name << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+#endif
+
+ dynmod *mod = new dynmod; // encapsulates the function and module handler.
+ mod->the_func = the_func ; // the function to execute
+ mod->the_module = the_module; // the module handler to close if function
+ // is not needed anymore.
+ pthread_mutex_lock ( &mut_map_mods );
+ map_mods->add_elem ( mod, s_name );
+ pthread_mutex_unlock( &mut_map_mods );
+
+// DO NOT CLOSE AS LONG THERE EXIST A POINTER TO THE FUNCTION
+// dlclose( module );
+
+ return mod;
+}
+
+dynmod*
+modl::get_module( string s_name )
+{
+ pthread_mutex_lock ( &mut_map_mods );
+ dynmod* mod = map_mods->get_elem( s_name );
+ pthread_mutex_unlock( &mut_map_mods );
+
+ return ! mod ? cache_module( s_name ) : mod;
+}
+
+#endif
diff --git a/modl.h b/modl.h
new file mode 100644
index 0000000..10f93ba
--- /dev/null
+++ b/modl.h
@@ -0,0 +1,29 @@
+// class modl declaration.
+
+#ifndef MODL_H
+#define MODL_H
+
+#include "incl.h"
+#include "hmap.h"
+
+using namespace std;
+
+
+class modl
+{
+private:
+ hmap<dynmod*,string>* map_mods;
+ pthread_mutex_t mut_map_mods;
+
+ static void dlclose_( dynmod* mod );
+ dynmod* cache_module ( string s_name );
+
+public:
+ modl();
+ ~modl();
+
+ dynmod* get_module ( string s_name );
+
+};
+
+#endif
diff --git a/msgs.h b/msgs.h
new file mode 100644
index 0000000..8c2ca13
--- /dev/null
+++ b/msgs.h
@@ -0,0 +1,36 @@
+#ifndef MSGS_H
+#define MSGS_H
+
+
+// several error messages which will apear by the clients.
+#define E_ALPNUM "The nick you have specified is not alphanumeric, please change that.<br><br>"
+#define E_NONICK "You need to specify a nick name.<br><br>"
+#define E_NOTONL "An error occured. Your nick is not online.<br><br>"
+#define E_ONLINE "The nick you have specified is already online. Try another nick.<br><br>"
+
+// all the custom messages for verbosity outputs. this messages may not
+// be used for html-template value substituation except the CONTACT and
+// DESCRIP variables. the verbosity output will appear in the standard
+// output of the server.
+// alphabetical ordered.
+#define CFILEOK "Parsing config file "
+#define CFILENO "Failed opening config file "
+#define CONNECT "Receiving connection "
+#define CONTACT "Contact: www.yChat.org, Mail@yChat.org "
+#define DESCRIP "yChat++ Copyright (C) 2003 Paul C. Buetow, Volker Richer "
+#define DOWNMSG "Shutting down "
+#define LOGINPR "Login procedure succeeded for nick "
+#define MODULEC "Caching module "
+#define NEWROOM "Adding room "
+#define REQUEST "Request string "
+#define SEPERAT "----------------------------------------- "
+#define SOCKCRT "Creating server socket "
+#define SOCKERR "Could not create socket. Trying next port "
+#define SOCKRDY "Server socket is ready. See port above "
+#define STARTMS "Starting up "
+#define TECACHE "Caching template "
+#define THREADS "Starting thread job "
+#define THREADE "Exiting thread job "
+#define VERSION "Version: yChat++ Basic 0.5.1"
+
+#endif
diff --git a/mutx.cpp b/mutx.cpp
new file mode 100644
index 0000000..eb75e90
--- /dev/null
+++ b/mutx.cpp
@@ -0,0 +1,20 @@
+// class mutx implementation.
+
+#ifndef s_mutx_CXX
+#define s_mutx_CXX
+
+#include "mutx.h"
+
+using namespace std;
+
+mutx::mutx()
+{
+ pthread_mutex_init( &mut_stdout, NULL );
+}
+
+mutx::~mutx()
+{
+ pthread_mutex_destroy( &mut_stdout );
+}
+
+#endif
diff --git a/mutx.h b/mutx.h
new file mode 100644
index 0000000..0438cb9
--- /dev/null
+++ b/mutx.h
@@ -0,0 +1,21 @@
+// class mutx declaration.
+
+#ifndef s_mutx_H
+#define s_mutx_H
+
+#include "incl.h"
+
+using namespace std;
+
+class mutx
+{
+public:
+ // this mutex is needed for sync stdout and sdterr of different threads.
+ pthread_mutex_t mut_stdout;
+
+ // public methods.
+ explicit mutx( ); // simple constructor.
+ ~mutx( ); // simple constructor.
+};
+
+#endif
diff --git a/name.cpp b/name.cpp
new file mode 100644
index 0000000..28033ff
--- /dev/null
+++ b/name.cpp
@@ -0,0 +1,32 @@
+// class name implementation.
+
+#ifndef NAME_CXX
+#define NAME_CXX
+
+#include "name.h"
+
+using namespace std;
+
+name::name( string s_name )
+{
+ set_name( s_name );
+}
+
+name::~name()
+{
+}
+
+string
+name::get_name() const
+{
+ return s_name;
+}
+
+void
+name::set_name( string s_name )
+{
+ this->s_name = s_name;
+}
+
+
+#endif
diff --git a/name.h b/name.h
new file mode 100644
index 0000000..b895389
--- /dev/null
+++ b/name.h
@@ -0,0 +1,28 @@
+// class name declaration.
+
+#ifndef NAME_H
+#define NAME_H
+
+#include "incl.h"
+
+using namespace std;
+
+class name
+{
+protected:
+ // private members:
+ string s_name; // object's name.
+
+public:
+ virtual string get_name ( ) const;
+ virtual void set_name ( string s_name );
+
+
+ // public methods:
+ explicit name( ) { }; // a standard constructor.
+ explicit name( string s_name ); // a standard constructor.
+ ~name( );
+
+};
+
+#endif
diff --git a/pool.cpp b/pool.cpp
new file mode 100644
index 0000000..a8c1556
--- /dev/null
+++ b/pool.cpp
@@ -0,0 +1,214 @@
+// class pool implementation.
+
+#ifndef POOL_CXX
+#define POOL_CXX
+
+#include "pool.h"
+
+#include "s_conf.h"
+#include "s_mutx.h"
+#include "s_tool.h"
+#include "thrd.h"
+
+using namespace std;
+
+pool::pool()
+{
+ i_thrd_pool_size = s_tool::string2int( s_conf::get().get_val( "THRDPOOL" ) );
+ i_thrd_pool_queue = s_tool::string2int( s_conf::get().get_val( "THRDQUEU" ) );
+
+ tpool_init( &thread_pool, i_thrd_pool_size, i_thrd_pool_queue, 0 );
+}
+
+pool::~pool()
+{
+ // tpool_destroy ...
+}
+
+void
+pool::tpool_init( tpool_t *tpoolp, int num_worker_threads, int max_queue_size, int do_not_block_when_full )
+{
+ int i, rtn;
+ tpool_t tpool;
+
+ // allocate a pool data structure
+ if (( tpool = (tpool_t) malloc( sizeof( struct tpool ) ) ) == NULL )
+ {
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cerr << "malloc" << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+ exit(-1);
+ }
+
+ // initialize th fields
+ tpool->num_threads = num_worker_threads;
+ tpool->max_queue_size = max_queue_size;
+ tpool->do_not_block_when_full = do_not_block_when_full;
+
+ if ( ( tpool->threads = (pthread_t*) malloc( sizeof( pthread_t ) *num_worker_threads ) ) == NULL )
+ {
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cerr << "malloc" << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+ exit(-1);
+ }
+
+ tpool->cur_queue_size = 0;
+ tpool->queue_head = NULL;
+ tpool->queue_tail = NULL;
+ tpool->queue_closed = 0;
+ tpool->shutdown = 0;
+
+ if ( ( rtn = pthread_mutex_init( &(tpool->queue_lock), NULL ) ) != 0 )
+ {
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cerr << "pthread_mutex_init " << strerror( rtn ) << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+ exit(-1);
+ }
+
+ else if ( ( rtn = pthread_cond_init( &(tpool->queue_not_empty), NULL ) ) != 0 )
+ {
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cerr << "pthread_cond_init " << strerror( rtn ) << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+ exit(-1);
+ }
+
+ else if ( ( rtn = pthread_cond_init( &(tpool->queue_not_full), NULL ) ) != 0 )
+ {
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cerr << "pthread_cond_init " << strerror( rtn ) << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+ exit(-1);
+ }
+
+ else if ( ( rtn = pthread_cond_init( &(tpool->queue_empty), NULL ) ) != 0 )
+ {
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cerr << "pthread_cond_init " << strerror( rtn ) << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+ exit(-1);
+ }
+ // create threads
+ for ( i = 0; i < num_worker_threads; i++ )
+ pthread_create( &(tpool->threads[i]) , NULL, tpool_thread, (void*)tpool );
+
+ *tpoolp = tpool;
+}
+
+void*
+pool::tpool_thread( void* arg )
+{
+ tpool_t tpool = (tpool_t) arg;
+ tpool_work_t *my_workp;
+
+ while( true )
+ {
+ pthread_mutex_lock( &(tpool->queue_lock) );
+
+ while ( (tpool->cur_queue_size == 0) && (!tpool->shutdown) )
+ pthread_cond_wait( &(tpool->queue_not_empty), &(tpool->queue_lock) );
+
+ if (tpool->shutdown)
+ {
+ pthread_mutex_unlock( &(tpool->queue_lock) );
+ pthread_exit( NULL );
+ }
+
+ my_workp = tpool->queue_head;
+ tpool->cur_queue_size--;
+
+ if ( tpool->cur_queue_size == 0)
+ tpool->queue_head = tpool->queue_tail = NULL;
+
+ else
+ tpool->queue_head = my_workp->next;
+
+ if ( ( ! tpool->do_not_block_when_full ) &&
+ ( tpool->cur_queue_size == ( tpool->max_queue_size - 1 ) ) )
+ pthread_cond_signal( &(tpool->queue_not_full) );
+
+ if ( tpool->cur_queue_size == 0 )
+ pthread_cond_signal( &(tpool->queue_empty) );
+
+ pthread_mutex_unlock( &(tpool->queue_lock) );
+ (*(my_workp->routine))(my_workp->arg);
+ free((void*)my_workp);
+ }
+}
+
+void pool::run_func( void *v_pointer )
+{
+#ifdef VERBOSE
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cout << THREADS << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+#endif
+
+ // recasting the client thread object.
+ thrd *t = (thrd*) v_pointer;
+
+ // start parsing the client request and sending response's back.
+ t-> run ();
+
+ // close the client socket.
+ t->~thrd();
+
+ free(v_pointer);
+
+#ifdef VERBOSE
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cout << THREADE << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+#endif
+}
+
+int
+pool::tpool_add_work( tpool_t tpool, void(*routine)(void*), void* arg ) ///
+{
+ tpool_work_t *workp;
+ pthread_mutex_lock( &(tpool->queue_lock) );
+
+ if( ( tpool->cur_queue_size == tpool->max_queue_size ) &&
+ tpool->do_not_block_when_full )
+ {
+ pthread_mutex_unlock( &(tpool->queue_lock) );
+ return -1;
+ }
+
+ while( ( tpool->cur_queue_size == tpool->max_queue_size ) &&
+ ( ! ( tpool->shutdown || tpool->queue_closed ) ) )
+ pthread_cond_wait( &(tpool->queue_not_full), &(tpool->queue_lock) );
+
+ if( tpool->shutdown || tpool->queue_closed )
+ {
+ pthread_mutex_unlock( &tpool->queue_lock );
+ return -1;
+ }
+
+ // allocate work structure:
+ workp = (tpool_work_t*) malloc( sizeof( tpool_work_t ) );
+
+ workp->routine = routine;
+ workp->arg = arg;
+ workp->next = NULL;
+
+ if( tpool->cur_queue_size == 0 )
+ {
+ tpool->queue_tail = tpool->queue_head = workp;
+ }
+
+ else
+ {
+ tpool->queue_tail->next = workp;
+ tpool->queue_tail = workp;
+ }
+
+ tpool->cur_queue_size++;
+ pthread_cond_signal( &(tpool->queue_not_empty) );
+ pthread_mutex_unlock( &(tpool->queue_lock) );
+ return 1;
+}
+
+#endif
diff --git a/pool.h b/pool.h
new file mode 100644
index 0000000..358b79f
--- /dev/null
+++ b/pool.h
@@ -0,0 +1,77 @@
+// class pool declaration.
+
+#ifndef POOL_H
+#define POOL_H
+
+#include "incl.h"
+
+using namespace std;
+
+class pool
+{
+private:
+ typedef struct tpool_work
+ {
+ void (*routine)(void*); ///
+ void *arg;
+ struct tpool_work *next;
+ }
+ tpool_work_t;
+
+ typedef struct tpool
+ {
+ // pool characteristics:
+ int num_threads;
+ int max_queue_size;
+ int do_not_block_when_full;
+
+ // pool state
+ pthread_t *threads;
+ int cur_queue_size;
+
+ tpool_work_t *queue_head;
+ tpool_work_t *queue_tail;
+
+ pthread_mutex_t queue_lock;
+ pthread_cond_t queue_not_empty;
+ pthread_cond_t queue_not_full;
+ pthread_cond_t queue_empty;
+
+ int queue_closed;
+ int shutdown;
+ }
+ *tpool_t;
+
+ int i_thrd_pool_size;
+ int i_thrd_pool_queue;
+
+ tpool_t thread_pool;
+
+ virtual void
+ tpool_init( tpool_t *tpoolp, int num_worker_threads, int max_queue_size, int do_not_block_when_full );
+
+ virtual int
+ tpool_add_work( tpool_t tpool, void(*routine)(void*), void* arg );
+
+// virtual void
+// tpool_destroy( tpool_t tpoolp, int finish );
+
+ static void*
+ tpool_thread( void* arg);
+
+ static void
+ run_func( void *v_pointer );
+
+ // public methods:
+public:
+ explicit pool( );
+ ~pool();
+
+ // inline (speed)!
+ void run( void *arg )
+ {
+ tpool_add_work( thread_pool, run_func, arg );
+ }
+};
+
+#endif
diff --git a/reqp.cpp b/reqp.cpp
new file mode 100644
index 0000000..d02afb8
--- /dev/null
+++ b/reqp.cpp
@@ -0,0 +1,291 @@
+// class reqp implementation.
+
+#ifndef REQP_CXX
+#define REQP_CXX
+
+#include "reqp.h"
+#include "s_chat.h"
+#include "s_html.h"
+#include "s_mutx.h"
+#include "s_sock.h"
+#include "s_tool.h"
+using namespace std;
+
+// inititialization of static members.
+string reqp::HTTP_CODEOK = "HTTP/1.1 200 OK\n";
+string reqp::HTTP_SERVER = "Server: yChat (Unix)\n";
+string reqp::HTTP_CONTAC = "Contact: www.yChat.org\n";
+string reqp::HTTP_CACHEC = "Expires: 0\nCache-control: no-cache\nPragma: no-cache\n";
+string reqp::HTTP_CONNEC = "Connection: keep-alive\n";
+string reqp::HTTP_COTYPE = "Content-Type: ";
+
+reqp::reqp( )
+{
+}
+
+string
+reqp::get_url( thrd* p_thrd, string s_req, map_string &map_params )
+{
+ auto unsigned int pos;
+ string s_ret ( "" );
+ string s_vars( "" );
+ auto int i_request;
+
+ i_request= ( s_req.find("GET",0) != string::npos ) ? RQ_GET : RQ_POST;
+
+ pos = s_req.find( "HTTP", 0 );
+
+ if( i_request == RQ_GET )
+ s_ret.append( s_req.substr( 5, pos-6 ) );
+ else
+ s_ret.append( s_req.substr( 6, pos-7 ) );
+
+ // remove ".." from the request.
+ do
+ {
+ pos = s_ret.find( "../", 0 );
+
+ if ( pos == string::npos )
+ break;
+
+ s_ret.replace( pos, pos+2, "" );
+ }
+ while( true );
+
+ // do not add the string behind "?" tp s_ret and add all params behind "?" to map_params.
+ if( i_request == RQ_GET )
+ pos = s_ret.find( "?", 0 );
+ else
+ pos = s_req.find("\r\n\r\n", 0);
+
+ auto string s_params( "" );
+ if ( pos != string::npos )
+ {
+ if( i_request == RQ_GET )
+ s_params.append( s_ret.substr( pos+1, s_ret.length() -pos-1 ) );
+
+ else
+ s_params = s_req.substr( pos+4, s_req.length() -pos-1 );
+
+ s_ret = s_ret.substr( 0, pos );
+ }
+
+ if ( i_request == RQ_POST && s_params.empty() )
+ {
+ char c_req[READBUF];
+
+ if ( read ( p_thrd->get_sock() , c_req, READBUF ) <= 0 )
+ return "NOBYTE";
+
+ s_params = string( strstr( c_req, "event" ) );
+ }
+
+ auto unsigned int pos2;
+ do
+ {
+ pos = s_params.find( "=", 0 );
+ if ( pos == string::npos )
+ break;
+
+ pos2 = s_params.find( "&", 0 );
+ if ( pos2 == string::npos )
+ {
+ auto string sValue( s_params.substr(pos+1, s_params.length()-pos-1) );
+ auto string tmpstr( url_decode(sValue) );
+ map_params[ s_params.substr( 0, pos ) ] = tmpstr;
+ break;
+ }
+
+ auto string s_temp= s_params.substr( pos+1, pos2-pos-1 );
+ map_params[ s_params.substr( 0, pos ) ] = url_decode(s_temp);
+
+ s_params = s_params.substr( pos2+1, s_params.length()-pos2-1 );
+ }
+ while( true );
+
+#ifdef VERBOSE
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cout << REQUEST << s_ret << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+#endif
+
+ if ( s_ret.empty() )
+ s_ret = s_conf::get().get_val( "STARTMPL" );
+
+ map_params["request"] = s_ret;
+
+ return s_ret;
+}
+
+string
+reqp::get_content_type( string s_file )
+{
+ string s_ext=s_tool::getExtension( s_file );
+
+ if(s_ext=="")
+ s_ext="DEFAULT";
+
+ return s_conf::get().get_val( "CT_"+s_ext );
+}
+void
+reqp::parse_headers( string s_req, map_string &map_params )
+{
+ int pos = s_req.find("\n");
+ if(pos!=string::npos)
+ map_params["QUERY_STRING"]=s_tool::trim(s_req.substr(0,pos-1));
+
+ while(pos!=string::npos)
+ {
+ auto string s_line=s_req.substr(0,pos);
+ auto int pos2=s_line.find(":");
+ if(pos2!=string::npos)
+ {
+ auto string key=s_tool::trim(s_line.substr(0, pos2));
+ auto string value=s_tool::trim(s_line.substr(pos2+1));
+
+ map_params[key]=value;
+
+
+ }
+ s_req=s_req.substr(s_line.size()+1);
+ pos=s_req.find("\n");
+ }
+
+}
+
+
+int
+reqp::htoi(string *s)
+{
+ int value;
+ int c;
+
+ c=s->c_str()[0];
+ if(isupper(c))
+ c=tolower(c);
+
+ value=(c>='0' && c<='9'?c-'0':c-'a'+10)*16;
+
+ c=s->c_str()[1];
+ if(isupper(c))
+ c=tolower(c);
+
+ value+=c>='0' && c<='9'?c-'0':c-'a'+10;
+ return value;
+}
+
+string
+reqp::url_decode( string s_str )
+{
+ auto string sDest="";
+ int len = s_str.size();
+
+ for(int i=0;i<len;i++)
+ {
+ char ch = s_str.at(i);
+ if(ch=='+')
+ {
+ sDest+=" ";
+ }
+ else if(ch=='%')
+ {
+ auto string sTmp=s_str.substr(i+1,2);
+ ch=(char)htoi(&sTmp);
+ sDest+=ch;
+ i+=2;
+
+ }
+ else
+
+ sDest+=ch;
+ }
+ return sDest;
+}
+
+string
+reqp::get_from_header( string s_req, string s_hdr )
+{
+ auto unsigned int pos[2];
+ pos[0] = s_req.find( s_hdr, 0 );
+ pos[1] = s_req.find( "\n", pos[0] );
+
+ auto int i_length = s_hdr.length();
+ return s_req.substr( pos[0]+i_length, pos[1]-pos[0]-i_length-1 );
+}
+
+string
+reqp::parse( thrd* p_thrd, string s_req, map_string &map_params )
+{
+
+ // store all request informations in map_params. store the url in
+ // map_params["request"].
+
+ if ( get_url( p_thrd, s_req, map_params ).compare("NOBYTE") == 0 )
+ map_params["request"] = s_conf::get().get_val("NOTFOUND");
+
+ parse_headers( s_req, map_params );
+ // create the http header.
+ string s_rep( HTTP_CODEOK ); s_rep.append( HTTP_SERVER );
+ s_rep.append( HTTP_CONTAC ); s_rep.append( HTTP_CACHEC );
+ s_rep.append( HTTP_CONNEC ); s_rep.append( HTTP_COTYPE );
+ s_rep.append( get_content_type( map_params["request"] ) );
+ s_rep.append("\r\n\r\n");
+
+ // check the event variable.
+
+ string s_event( map_params["event"] );
+ if ( ! s_event.empty() )
+ {
+ // login procedure.
+ if ( s_event == "login" )
+ {
+ s_chat::get().login( map_params );
+ }
+
+ else
+ {
+ bool b_found;
+
+// user* p_user = s_chat::get().get_user( map_params["nick"], b_found );
+ sess *sess_temp=s_sman::get().getSession( map_params["tmpid"] );
+ user *p_user;
+ if(sess_temp!=NULL)
+ {
+ string *s_nick=static_cast<string*>(sess_temp->getValue(string("nick")));
+ p_user = s_chat::get().get_user( *s_nick, b_found);
+ }
+ else
+ return s_rep;
+ if ( ! b_found )
+ {
+ map_params["INFO"] = E_NOTONL;
+ map_params["request"] = s_conf::get().get_val( "STARTMPL" ); // redirect to the startpage.
+ }
+ // if a message post.
+ else if ( s_event == "post" )
+ s_chat::get().post( p_user, map_params );
+
+
+ // if a chat stream
+ else if ( s_event == "stream" )
+ {
+ string s_msg(s_html::get().parse( map_params ) );
+ p_user->msg_post( &s_msg);
+ s_sock::get().chat_stream( p_thrd->get_sock(), p_user, map_params );
+ }
+
+ // if a request for the online list of the active room.
+ else if ( s_event == "online" )
+ s_html::get().online_list( p_user, map_params );
+ }
+ }
+
+ // parse and get the requested html-template and also use
+ // the values stored in map_params for %%KEY%% substituations.
+ s_rep.append( s_html::get().parse( map_params ) );
+
+ // return the parsed html-template.
+ return s_rep;
+}
+
+#endif
diff --git a/reqp.h b/reqp.h
new file mode 100644
index 0000000..399c751
--- /dev/null
+++ b/reqp.h
@@ -0,0 +1,47 @@
+// class reqp declaration. this class parses the client requests.
+
+#ifndef REQP_H
+#define REQP_H
+
+#define RQ_GET 1
+#define RQ_POST 2
+
+#include <map>
+#include "incl.h"
+#include "thrd.h"
+
+using namespace std;
+
+typedef map<string, string, less<string> > map_string;
+
+class reqp
+{
+private:
+ static string HTTP_CODEOK,
+ HTTP_CODENF,
+ HTTP_SERVER,
+ HTTP_CONTAC,
+ HTTP_CACHEC,
+ HTTP_CONNEC,
+ HTTP_COTYPE;
+
+ // returns the request url from thr client's http request header
+ // until the first "?" and stores all request parameter values
+ // ( behind "?" ) into map_params.
+ virtual string get_url( thrd* p_thrd, string s_req, map_string &map_params );
+ // returns a specific value of the client's http request header.
+ // ( s.t. like the User-Agent, Referer etc... ).
+ virtual string get_from_header( string s_req, string s_hdr );
+
+ virtual int htoi( string *s );
+
+public:
+ // public methods.
+ explicit reqp( ); // simple constructor.
+ virtual string parse( thrd* p_thrd, string s_req, map_string &map_params );
+ virtual string url_decode ( string );
+ virtual string get_content_type( string );
+ virtual void parse_headers( string s_req, map_string &map_params );
+};
+
+#endif
diff --git a/room.cpp b/room.cpp
new file mode 100644
index 0000000..0e905e6
--- /dev/null
+++ b/room.cpp
@@ -0,0 +1,18 @@
+// class room implementation.
+
+#ifndef ROOM_CXX
+#define ROOM_CXX
+
+#include "room.h"
+
+using namespace std;
+
+room::room( string s_name ) : name( s_name )
+{
+}
+
+room::~room()
+{
+}
+
+#endif
diff --git a/room.h b/room.h
new file mode 100644
index 0000000..f351b9a
--- /dev/null
+++ b/room.h
@@ -0,0 +1,34 @@
+// class room declaration.
+
+#ifndef ROOM_H
+#define ROOM_H
+
+#include "incl.h"
+#include "base.h"
+#include "name.h"
+#include "user.h"
+
+using namespace std;
+
+class room : public base<user>, public name
+{
+private:
+
+public:
+ void add_user( user* p_user )
+ {
+ p_user->set_p_room( this );
+ add_elem( p_user );
+ }
+
+ user* get_user( string &s_name, bool &b_found )
+ {
+ return static_cast<user*>( get_elem( s_name, b_found ) );
+ }
+
+ // public methods:
+ explicit room( string s_name ); // a constructor.
+ ~room(); // room destructor.
+};
+
+#endif
diff --git a/s_chat.cpp b/s_chat.cpp
new file mode 100644
index 0000000..9e0d01b
--- /dev/null
+++ b/s_chat.cpp
@@ -0,0 +1,10 @@
+#ifndef GCHT_CXX
+#define GCHT_CXX
+
+#include "s_chat.h"
+
+using namespace std;
+
+chat* s_chat::obj;
+
+#endif
diff --git a/s_chat.h b/s_chat.h
new file mode 100644
index 0000000..4162180
--- /dev/null
+++ b/s_chat.h
@@ -0,0 +1,26 @@
+#ifndef GCHT_H
+#define GCHT_H
+
+#include "chat.h"
+
+using namespace std;
+
+class s_chat
+{
+private:
+ static chat* obj;
+
+public:
+ static void init()
+ {
+ obj = new chat();
+ }
+
+ static chat& get()
+ {
+ return *obj;
+ }
+};
+
+
+#endif
diff --git a/s_conf.cpp b/s_conf.cpp
new file mode 100644
index 0000000..ea1c05a
--- /dev/null
+++ b/s_conf.cpp
@@ -0,0 +1,10 @@
+#ifndef GCON_CXX
+#define GCON_CXX
+
+#include "s_conf.h"
+
+using namespace std;
+
+conf* s_conf::obj;
+
+#endif
diff --git a/s_conf.h b/s_conf.h
new file mode 100644
index 0000000..09c4ea7
--- /dev/null
+++ b/s_conf.h
@@ -0,0 +1,26 @@
+#ifndef GCON_H
+#define GCON_H
+
+#include "conf.h"
+
+using namespace std;
+
+class s_conf
+{
+private:
+ static conf* obj;
+
+public:
+ static void init()
+ {
+ obj = new conf( CONFILE );
+ }
+
+ static conf& get()
+ {
+ return *obj;
+ }
+};
+
+
+#endif
diff --git a/s_html.cpp b/s_html.cpp
new file mode 100644
index 0000000..0899abe
--- /dev/null
+++ b/s_html.cpp
@@ -0,0 +1,10 @@
+#ifndef GHTM_CXX
+#define GHTM_CXX
+
+#include "s_html.h"
+
+using namespace std;
+
+html* s_html::obj;
+
+#endif
diff --git a/s_html.h b/s_html.h
new file mode 100644
index 0000000..af8297b
--- /dev/null
+++ b/s_html.h
@@ -0,0 +1,26 @@
+#ifndef GHTM_H
+#define GHTM_H
+
+#include "html.h"
+
+using namespace std;
+
+class s_html
+{
+private:
+ static html* obj;
+
+public:
+ static void init()
+ {
+ obj = new html();
+ }
+
+ static html& get()
+ {
+ return *obj;
+ }
+};
+
+
+#endif
diff --git a/s_lang.cpp b/s_lang.cpp
new file mode 100644
index 0000000..41c2089
--- /dev/null
+++ b/s_lang.cpp
@@ -0,0 +1,10 @@
+#ifndef GCON_CXX
+#define GCON_CXX
+
+#include "s_lang.h"
+
+using namespace std;
+
+lang* s_lang::obj;
+
+#endif
diff --git a/s_lang.h b/s_lang.h
new file mode 100644
index 0000000..03851b9
--- /dev/null
+++ b/s_lang.h
@@ -0,0 +1,26 @@
+#ifndef GLANG_H
+#define GLANG_H
+
+#include "lang.h"
+#include "s_conf.h"
+using namespace std;
+
+class s_lang
+{
+private:
+ static lang* obj;
+
+public:
+ static void init()
+ {
+ obj = new lang( s_conf::get().get_val( "LANGUAGE" ) );
+ }
+
+ static lang& get()
+ {
+ return *obj;
+ }
+};
+
+
+#endif
diff --git a/s_modl.cpp b/s_modl.cpp
new file mode 100644
index 0000000..f6a5913
--- /dev/null
+++ b/s_modl.cpp
@@ -0,0 +1,10 @@
+#ifndef GMOD_CXX
+#define GMOD_CXX
+
+#include "s_modl.h"
+
+using namespace std;
+
+modl* s_modl::obj;
+
+#endif
diff --git a/s_modl.h b/s_modl.h
new file mode 100644
index 0000000..b5267dd
--- /dev/null
+++ b/s_modl.h
@@ -0,0 +1,26 @@
+#ifndef GMOD_H
+#define GMOD_H
+
+#include "modl.h"
+
+using namespace std;
+
+class s_modl
+{
+private:
+ static modl* obj;
+
+public:
+ static void init()
+ {
+ obj = new modl();
+ }
+
+ static modl& get()
+ {
+ return *obj;
+ }
+};
+
+
+#endif
diff --git a/s_mutx.cpp b/s_mutx.cpp
new file mode 100644
index 0000000..33c8385
--- /dev/null
+++ b/s_mutx.cpp
@@ -0,0 +1,10 @@
+#ifndef GMUT_CXX
+#define GMUT_CXX
+
+#include "s_mutx.h"
+
+using namespace std;
+
+mutx* s_mutx::obj;
+
+#endif
diff --git a/s_mutx.h b/s_mutx.h
new file mode 100644
index 0000000..24c0f97
--- /dev/null
+++ b/s_mutx.h
@@ -0,0 +1,26 @@
+#ifndef GMUT_H
+#define GMUT_H
+
+#include "mutx.h"
+
+using namespace std;
+
+class s_mutx
+{
+private:
+ static mutx* obj;
+
+public:
+ static void init()
+ {
+ obj = new mutx();
+ }
+
+ static mutx& get()
+ {
+ return *obj;
+ }
+};
+
+
+#endif
diff --git a/s_sman.cpp b/s_sman.cpp
new file mode 100644
index 0000000..bfb1efd
--- /dev/null
+++ b/s_sman.cpp
@@ -0,0 +1,10 @@
+#ifndef GSMAN_CXX
+#define GSMAN_CXX
+
+#include "s_sman.h"
+
+using namespace std;
+
+sman* s_sman::obj;
+
+#endif
diff --git a/s_sman.h b/s_sman.h
new file mode 100644
index 0000000..ff3a7c5
--- /dev/null
+++ b/s_sman.h
@@ -0,0 +1,26 @@
+#ifndef GSMAN_H
+#define GSMAN_H
+
+#include "sman.h"
+
+using namespace std;
+
+class s_sman
+{
+private:
+ static sman* obj;
+
+public:
+ static void init()
+ {
+ obj = new sman();
+ }
+
+ static sman& get()
+ {
+ return *obj;
+ }
+};
+
+
+#endif
diff --git a/s_sock.cpp b/s_sock.cpp
new file mode 100644
index 0000000..dd80e71
--- /dev/null
+++ b/s_sock.cpp
@@ -0,0 +1,10 @@
+#ifndef GSOC_CXX
+#define GSOC_CXX
+
+#include "s_sock.h"
+
+using namespace std;
+
+sock* s_sock::obj;
+
+#endif
diff --git a/s_sock.h b/s_sock.h
new file mode 100644
index 0000000..d570e0c
--- /dev/null
+++ b/s_sock.h
@@ -0,0 +1,26 @@
+#ifndef GSOC_H
+#define GSOC_H
+
+#include "sock.h"
+
+using namespace std;
+
+class s_sock
+{
+private:
+ static sock* obj;
+
+public:
+ static void init()
+ {
+ obj = new sock();
+ }
+
+ static sock& get()
+ {
+ return *obj;
+ }
+};
+
+
+#endif
diff --git a/s_tool.cpp b/s_tool.cpp
new file mode 100644
index 0000000..ae6357a
--- /dev/null
+++ b/s_tool.cpp
@@ -0,0 +1,111 @@
+#ifndef s_tool_CXX
+#define s_tool_CXX
+
+#include <ctype.h>
+#include <time.h>
+#include "s_tool.h"
+
+bool
+s_tool::is_alpha_numeric( string &s_digit )
+{
+ auto const char *digit = s_digit.c_str();
+ auto int i_len = strlen( digit );
+
+ for( int i=0; i<i_len; i++ )
+ {
+ if ( ! isalnum( *digit ) )
+ return false;
+ digit++;
+ }
+
+ return true;
+}
+string
+s_tool::trim( string s_str )
+{
+ if(s_str.empty())return "";
+ char c_cur=s_str[0];
+ auto int pos=0;
+// left trim
+ while(c_cur==' ' || c_cur == '\n' || c_cur == '\r')
+ {
+ s_str.erase(pos,1);
+
+ c_cur=s_str[++pos];
+
+ }
+// right trim
+
+ pos=s_str.size();
+ c_cur=s_str[s_str.size()];
+
+ while(c_cur==' ' || c_cur == '\n' || c_cur == '\0' || c_cur == '\r')
+ {
+ s_str.erase(pos,1);
+ c_cur=s_str[--pos];
+
+ }
+ return s_str;
+}
+
+string
+s_tool::getExtension( string s_file )
+{
+ int pos = s_file.find_last_of(".");
+ if(pos != string::npos)
+ {
+ string s_ext=s_file.substr(pos+1, s_file.size()-(pos+1));
+ for(int i = 0;i<s_ext.size();i++)
+ s_ext[i]=toupper(s_ext[i]);
+ return s_ext;
+ }
+ return "";
+}
+
+int
+s_tool::string2int( string s_digit )
+{
+ auto const char *digit = s_digit.c_str();
+ int result = 0;
+
+ // Convert each digit char and add into result.
+ while (*digit >= '0' && *digit <='9') {
+ result = (result * 10) + (*digit - '0');
+ digit++;
+ }
+
+ // Check that there were no non-digits at end.
+ if (*digit != 0) {
+ return -1;
+ }
+
+ return result;
+}
+
+long
+s_tool::unixtime()
+{
+ return (long) time( NULL );
+}
+
+
+void
+s_tool::strip_html( string *s_str )
+{
+ auto int i_pos;
+
+ if((i_pos=s_str->find("<",0))==string::npos)
+ return;
+ while(true)
+ {
+
+ s_str->replace(i_pos,1,"&lt;");
+
+ if((i_pos=s_str->find("<",0))==string::npos)
+ return;
+
+ }
+
+
+}
+#endif
diff --git a/s_tool.h b/s_tool.h
new file mode 100644
index 0000000..f778c37
--- /dev/null
+++ b/s_tool.h
@@ -0,0 +1,19 @@
+#ifndef s_tool_H
+#define s_tool_H
+
+#include "incl.h"
+
+using namespace std;
+
+class s_tool
+{
+public:
+ static bool is_alpha_numeric( string &s_digit );
+ static int string2int( string s_digit );
+ static string trim( string s_str );
+ static long unixtime();
+ static void strip_html( string *s_str);
+ static string getExtension( string s_file );
+};
+
+#endif
diff --git a/sess.cpp b/sess.cpp
new file mode 100644
index 0000000..10c4c8f
--- /dev/null
+++ b/sess.cpp
@@ -0,0 +1,35 @@
+#ifndef SESS_CPP
+#define SESS_CPP
+
+#include "sess.h"
+
+sess::sess( string s_id )
+{
+ this->sess_id=s_id;
+}
+
+string sess::getId(){ return this->sess_id; }
+
+
+void sess::invalidate() {
+ this->sess_id="0";
+ this->sess_values.clear();
+}
+
+void sess::setValue( string s_key, void *lpvalue )
+{
+ this->sess_values[s_key]=lpvalue;
+}
+void *sess::getValue( string s_key )
+{
+ return this->sess_values[s_key];
+}
+string sess::dump()
+{
+ string s_ret=string("Session Dump of Session ") + this->getId();
+ map<string, void*>::const_iterator it;
+ for(it=this->sess_values.begin();it!=this->sess_values.end();it++)
+ s_ret=s_ret + "\nkey: " + it->first;
+ return s_ret;
+}
+#endif
diff --git a/sess.h b/sess.h
new file mode 100644
index 0000000..8d7b08e
--- /dev/null
+++ b/sess.h
@@ -0,0 +1,28 @@
+#ifndef s_sess_H
+#define s_sess_H
+
+#include "incl.h"
+#include "cont.h"
+#include "name.h"
+#include <map>
+#include <string>
+#include "hmap.h"
+using namespace std;
+
+typedef map<string, void *> sess_map;
+
+class sess : public cont, name
+{
+
+ private:
+ sess_map sess_values;
+ string sess_id;
+ public:
+ sess(string s_id);
+ string getId();
+ void setValue(string s_key, void *lpvalue);
+ void *getValue( string s_key );
+ void invalidate();
+ string dump();
+};
+#endif
diff --git a/sman.cpp b/sman.cpp
new file mode 100644
index 0000000..4c95b32
--- /dev/null
+++ b/sman.cpp
@@ -0,0 +1,48 @@
+#ifndef SMAN_CXX
+#define SMAN_CXX
+
+#include "sman.h"
+
+sman::sman()
+{
+ this->sessions=new hmap<sess *, string>(80);
+ this->sessioncount=0;
+}
+sman::~sman()
+{
+ delete this->sessions;
+}
+string sman::generateId( int len )
+{
+ string valid_chars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
+ string s_ret="";
+ srand(time(0)+160682);
+ for(int i=0;i<len;i++)
+ {
+ int i_char=rand() % 64;
+ s_ret+=valid_chars[i_char];
+ }
+ return s_ret;
+}
+sess *sman::createSession( )
+{
+ string new_id=this->generateId(s_tool::string2int( s_conf::get().get_val( "SESSION_LENGTH" ) ) );
+
+ sess *new_sess= new sess( new_id );
+
+ this->sessioncount++;
+ this->sessions->add_elem( new_sess, new_id );
+
+ return new_sess;
+}
+
+sess *sman::getSession( string s_id )
+{
+ return this->sessions->get_elem( s_id );
+}
+void sman::destroySession( string s_id )
+{
+ this->sessioncount--;
+ this->sessions->del_elem( s_id );
+}
+#endif
diff --git a/sman.h b/sman.h
new file mode 100644
index 0000000..336bdf1
--- /dev/null
+++ b/sman.h
@@ -0,0 +1,32 @@
+#ifndef SMAN_H
+#define SMAN_H
+
+#include "incl.h"
+#include "hmap.h"
+#include "sess.h"
+#include "s_tool.h"
+#include "s_conf.h"
+#include <cstdlib>
+
+using namespace std;
+
+class sman{
+
+ private:
+ hmap<sess *, string> *sessions;
+ string generateId( int len );
+ int sessioncount;
+ public:
+ sman();
+ ~sman();
+ sess *getSession( string s_id );
+ int getSessionCount( ) { return this->sessioncount; }
+ sess *createSession( );
+ void destroySession( string s_id );
+
+
+};
+
+
+#endif
+
diff --git a/sock.cpp b/sock.cpp
new file mode 100644
index 0000000..fb041fb
--- /dev/null
+++ b/sock.cpp
@@ -0,0 +1,238 @@
+// class sock implementation. the multiplex socket implementation has been token from the
+// GNU C Library Examples and modified in order to fit in here ( POSIX threads etc. ).
+
+#ifndef s_sock_CXX
+#define s_sock_CXX
+
+#include <unistd.h>
+
+#include "sock.h"
+#include "s_chat.h"
+#include "s_conf.h"
+#include "s_mutx.h"
+#include "s_tool.h"
+#include "s_lang.h"
+#include "s_sman.h"
+#include "chat.h"
+#include "user.h"
+
+using namespace std;
+
+sock::sock()
+{
+ this->b_run = true;
+ this->i_req = 0;
+ this->req_parser = new reqp();
+ this->thrd_pool = new pool();
+ this->log_daemon = new logd(s_conf::get().get_val( "ACCESS_LOG" ));
+}
+
+void
+sock::chat_stream( int i_sock, user* p_user, map_string &map_params )
+{
+ string s_msg( "\n" );
+
+ pthread_mutex_lock ( &(p_user->mut_message) );
+
+ for ( int i = 0; i < PUSHSTR; i++ )
+ send( i_sock, s_msg.c_str(), s_msg.size(), 0 );
+
+ do
+ {
+ s_msg = p_user->get_mess( );
+ if ( 0 > send( i_sock, s_msg.c_str(), s_msg.size(), 0 ) )
+ p_user->set_online( false );
+ pthread_cond_wait( &(p_user->cond_message), &(p_user->mut_message) );
+ }
+ while( p_user->get_online() );
+
+ // if there is still a message to send:
+ s_msg = p_user->get_mess( );
+ if ( ! s_msg.empty() )
+ send( i_sock, s_msg.c_str(), s_msg.size(), 0 );
+
+ pthread_mutex_unlock( &(p_user->mut_message) );
+
+ // remove the user from its room.
+ string s_user( p_user->get_name() );
+ p_user->get_p_room()->del_elem( s_user );
+
+ // post the room that the user has left the chat.
+ p_user->get_p_room()->msg_post( new string( p_user->get_name().append( s_lang::get().get_val( "USERLEAV" ) ) ) );
+ s_sman::get().destroySession( p_user->get_id() );
+ #ifdef VERBOSE
+ cout << s_user << " left | SessionCount: " << s_sman::get().getSessionCount() << endl;
+ #endif
+
+ p_user->~user();
+}
+
+int
+sock::make_socket( uint16_t i_port )
+{
+ int sock;
+ struct sockaddr_in name;
+
+ // create the server socket.
+ sock = socket (PF_INET, SOCK_STREAM, 0);
+ if (sock < 0)
+ {
+ cerr << "Sock: socket error" << endl;
+
+ if ( ++i_port > MAXPORT )
+ exit(-1);
+
+ cerr << SOCKERR << i_port << endl;
+ return make_socket( i_port );
+ }
+
+ // give the server socket a name.
+ name.sin_family = AF_INET;
+ name.sin_port = htons (i_port);
+ name.sin_addr.s_addr = htonl (INADDR_ANY);
+ int optval=1;
+
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof(int));
+
+ if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
+ {
+ cerr << "Sock: bind error" << endl;
+
+ if ( ++i_port > MAXPORT )
+ exit(-1);
+
+ cout << SOCKERR << i_port << endl;
+ return make_socket( i_port );
+ }
+
+ return sock;
+}
+
+int
+sock::read_write( thrd* p_thrd, int i_sock )
+{
+ char c_req[2048];
+
+ int i_bytes;
+ i_bytes = read (i_sock, c_req, 2048);
+
+ if (i_bytes < 0)
+ {
+ cerr << "Sock: read error " << endl;
+ }
+
+ else
+ {
+ // stores the request params.
+ map_string map_params;
+
+ // get the s_rep ( s_html response which will be send imediatly to the client
+ // and fill map_params with request values.
+ auto string s_temp=(string)c_req;
+ struct sockaddr_in client;
+ size_t size=sizeof(client);
+
+ getpeername( i_sock, (struct sockaddr *)&client, &size);
+
+ map_params["REMOTE_ADDR"]=inet_ntoa(client.sin_addr);
+ map_params["REMOTE_PORT"]=ntohs( client.sin_port);
+
+
+ string s_rep = req_parser->parse( p_thrd, string( c_req ), map_params );
+ // send s_rep to the client.
+ log_daemon->log(map_params);
+
+ send( i_sock, s_rep.c_str(), s_rep.size(), 0 );
+
+ // dont need those vals anymore.
+ map_params.clear();
+
+ return 0;
+ }
+
+ return -1;
+}
+
+int
+sock::start()
+{
+ auto int i_port = s_tool::string2int( s_conf::get().get_val( "SRVRPORT" ) );
+
+ int sock;
+ fd_set active_fd_set, read_fd_set;
+ int i;
+ struct sockaddr_in clientname;
+ size_t size;
+
+#ifdef VERBOSE
+ cout << SOCKCRT << "localhost:" << i_port << endl;
+#endif
+
+ // create the server socket and set it up to accept connections.
+ sock = make_socket ( i_port );
+
+ if (listen (sock, 1) < 0)
+ {
+ cerr << "Sock: listen error" << endl;
+ exit( EXIT_FAILURE );
+ }
+
+#ifdef VERBOSE
+ cout << SOCKRDY << endl;
+#endif
+
+ // initialize the set of active sockets.
+ FD_ZERO (&active_fd_set);
+ FD_SET (sock, &active_fd_set);
+
+ while( b_run )
+ {
+ // block until input arrives on one or more active sockets.
+ read_fd_set = active_fd_set;
+ if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
+ {
+ cerr << "Sock: select error" << endl;
+ exit( EXIT_FAILURE );
+ }
+
+ // service all the sockets with input pending.
+ for ( i = 0; i < FD_SETSIZE; i++ )
+ if ( FD_ISSET (i, &read_fd_set) )
+ {
+ if ( i == sock )
+ {
+ // connection request on original socket.
+ i_req++;
+ int new_sock;
+ size = sizeof (clientname);
+ new_sock = accept (sock,
+ (struct sockaddr *) &clientname,
+ &size);
+
+ if (new_sock < 0)
+ {
+ cerr << "Sock: accept error" << endl;
+ close ( new_sock );
+ }
+
+#ifdef VERBOSE
+ cout << CONNECT << i_req << " "
+ << inet_ntoa( clientname.sin_addr )
+ << ":"
+ << ntohs ( clientname.sin_port )
+ << endl;
+#endif
+
+ FD_SET (new_sock, &active_fd_set);
+ }
+
+ else
+ {
+ thrd_pool->run( (void*) new thrd( i ) );
+ FD_CLR( i, &active_fd_set );
+ }
+ }
+ }
+}
+
+#endif
diff --git a/sock.h b/sock.h
new file mode 100644
index 0000000..ea695c4
--- /dev/null
+++ b/sock.h
@@ -0,0 +1,53 @@
+// class sock declaration.
+
+#ifndef s_sock_H
+#define s_sock_H
+
+#include <queue>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include "incl.h"
+#include "pool.h"
+#include "reqp.h"
+#include "thrd.h"
+#include "user.h"
+#include "logd.h"
+using namespace std;
+
+class sock
+{
+private:
+ // total number of server requests.
+ unsigned long long int i_req;
+
+ bool b_run; // true while socket manager is running.
+ reqp* req_parser; // parses the http requests from clients.
+ pool* thrd_pool; // the thread pool.
+ logd* log_daemon; // the log daemon
+ // creates a server socket.
+ virtual int make_socket( uint16_t port );
+
+public:
+ // small inline methods:
+ bool get_run() const { return b_run; }
+ bool set_run( bool b_run ) { this->b_run = b_run; }
+
+ // public methods.
+ explicit sock( ); // simple constructor.
+ virtual int read_write( thrd* p_thrd, int filedes );
+ virtual int start();
+
+ // the chat stream there all the chat messages will sent through.
+ static void chat_stream( int i_sock, user* p_user, map_string &map_params );
+
+};
+
+#endif
diff --git a/thrd.cpp b/thrd.cpp
new file mode 100644
index 0000000..4bac39e
--- /dev/null
+++ b/thrd.cpp
@@ -0,0 +1,28 @@
+// class thrd implementation.
+
+#ifndef THRD_CXX
+#define THRD_CXX
+
+#include "thrd.h"
+#include "s_sock.h"
+
+using namespace std;
+
+thrd::thrd( int i_sock )
+{
+ this->i_sock = i_sock;
+}
+
+thrd::~thrd()
+{
+ shutdown ( get_sock() , 2 );
+ close ( get_sock() );
+}
+
+void
+thrd::run()
+{
+ s_sock::get().read_write( this, i_sock );
+}
+
+#endif
diff --git a/thrd.h b/thrd.h
new file mode 100644
index 0000000..fecdb49
--- /dev/null
+++ b/thrd.h
@@ -0,0 +1,26 @@
+// class thrd declaration.
+
+#ifndef THRD_H
+#define THRD_H
+
+#include "incl.h"
+
+using namespace std;
+
+class thrd
+{
+private:
+ int i_sock;
+
+public:
+
+ // small inline methods:
+ int get_sock() { return i_sock; }
+
+ // public methods:
+ explicit thrd( int i_sock );
+ ~thrd(); // destructor.
+ virtual void run();
+};
+
+#endif
diff --git a/todo.txt b/todo.txt
new file mode 100644
index 0000000..7e43eb2
--- /dev/null
+++ b/todo.txt
@@ -0,0 +1,11 @@
+BRAIN-STORMING:
+
+mysql
+security: tempid and crypto
+commands
+hash_map []-operator
+hash_map in cont
+several different html templatetes
+
+10: bugfixes
+20: goto 10
diff --git a/user.cpp b/user.cpp
new file mode 100644
index 0000000..4cda685
--- /dev/null
+++ b/user.cpp
@@ -0,0 +1,170 @@
+// class user implementation.
+
+#ifndef USER_CXX
+#define USER_CXX
+
+#include "user.h"
+#include "s_conf.h"
+#include "s_modl.h"
+#include "s_tool.h"
+
+using namespace std;
+
+user::user( string s_name ) : name( s_name )
+{
+ this -> b_online = true;
+ this -> l_time = s_tool::unixtime();
+ this -> s_col1 = s_conf::get().get_val( "USERCOL1" );
+
+ pthread_mutex_init( &mut_b_online, NULL);
+ pthread_mutex_init( &mut_i_sock , NULL);
+ pthread_mutex_init( &mut_l_time , NULL);
+ pthread_mutex_init( &mut_p_room , NULL);
+ pthread_mutex_init( &mut_s_mess , NULL);
+ pthread_cond_init ( &cond_message, NULL);
+ pthread_mutex_init( &mut_message , NULL);
+}
+
+user::~user()
+{
+ pthread_mutex_destroy( &mut_b_online );
+ pthread_mutex_destroy( &mut_i_sock );
+ pthread_mutex_destroy( &mut_l_time );
+ pthread_mutex_destroy( &mut_p_room );
+ pthread_mutex_destroy( &mut_s_mess );
+ pthread_cond_destroy ( &cond_message );
+ pthread_mutex_destroy( &mut_message );
+}
+
+void
+user::get_data( map_string *p_map_data )
+{
+ string s_req = (*p_map_data)["!get"];
+
+ // get the nick and the color of the user.
+ if ( s_req == "nick" )
+ (*p_map_data)[get_name()] = get_col1();
+}
+
+string
+user::get_mess( )
+{
+ string s_ret( "" );
+ pthread_mutex_lock ( &mut_s_mess );
+ s_ret.append( s_mess );
+ s_mess = *new string("");
+ pthread_mutex_unlock( &mut_s_mess );
+
+ return s_ret;
+}
+
+bool
+user::get_online( )
+{
+ bool b_ret;
+ pthread_mutex_lock ( &mut_b_online );
+ b_ret = b_online;
+ pthread_mutex_unlock( &mut_b_online );
+ return b_ret;
+}
+
+void
+user::set_online( bool b_online )
+{
+ pthread_mutex_lock ( &mut_b_online );
+ this -> b_online = b_online;
+ pthread_mutex_unlock( &mut_b_online );
+}
+
+room*
+user::get_p_room( )
+{
+ room* p_return;
+ pthread_mutex_lock ( &mut_p_room );
+ p_return = p_room;
+ pthread_mutex_unlock( &mut_p_room );
+ return p_return;
+}
+
+void
+user::set_p_room( room* p_room )
+{
+ pthread_mutex_lock ( &mut_p_room );
+ this -> p_room = p_room;
+ pthread_mutex_unlock( &mut_p_room );
+}
+
+int
+user::get_sock( )
+{
+ int i_ret;
+ pthread_mutex_lock ( &mut_i_sock );
+ i_ret = i_sock;
+ pthread_mutex_unlock( &mut_i_sock );
+ return i_ret;
+}
+
+void
+user::set_sock( int i_sock )
+{
+ pthread_mutex_lock ( &mut_i_sock );
+ this -> i_sock = i_sock;
+ pthread_mutex_unlock( &mut_i_sock );
+}
+
+void
+user::command( string &s_command )
+{
+
+ auto unsigned int pos = s_command.find( "/" );
+ while( pos != string::npos )
+ {
+ s_command.replace( pos, 1, "" );
+ pos = s_command.find( "/" );
+ }
+
+ string s_mod( "cmnd/yc_" );
+ s_mod.append( s_command ).append( ".so" );
+
+ dynmod *mod = s_modl::get().get_module( s_mod );
+
+ if ( mod == NULL )
+ {
+ msg_post( new string( s_lang::get().get_val( "ERRORCMD" ) ) );
+ return;
+ }
+
+ // execute the module.
+ ( *(mod->the_func) ) ( (void*) this );
+}
+
+void
+user::renew_stamp( )
+{
+ pthread_mutex_lock ( &mut_l_time );
+ l_time = s_tool::unixtime();
+ pthread_mutex_unlock( &mut_l_time );
+}
+
+void
+user::msg_post( string *p_msg )
+{
+ pthread_mutex_lock ( &mut_s_mess );
+ s_mess.append( *p_msg );
+ pthread_mutex_unlock( &mut_s_mess );
+
+ pthread_cond_signal( &cond_message );
+}
+
+void
+user::get_user_list( string &s_list, string &s_seperator )
+{
+ s_list.append( "<font color=\"" )
+ .append( get_col1() )
+ .append( "\">" )
+ .append( get_name() )
+ .append( "</font>\n" )
+ .append( s_seperator );
+
+}
+#endif
diff --git a/user.h b/user.h
new file mode 100644
index 0000000..75be662
--- /dev/null
+++ b/user.h
@@ -0,0 +1,84 @@
+// class user declaration.
+#ifndef USER_H
+#define USER_H
+
+#include "incl.h"
+#include "hmap.h"
+#include "name.h"
+#include "s_lang.h"
+using namespace std;
+
+class room;
+
+class user : public name
+{
+private:
+ // private members:
+ bool b_away; // true if user is away.
+ bool b_online; // true if user is online.
+ int i_sock; // user's stream socket descriptor.
+ long l_time; // user's last activity time.
+ rang r_rang; // user's rang ( see enum rang @ globals.h ).
+ rang r_oldr; // user's previous rang.
+ string s_id;
+ string s_agnt; // user's http user agent.
+ string s_away; // user's last away message.
+ string s_col1; // user's nick color.
+ string s_mess; // message string which has to be sent to the user.
+ room* p_room; // pointer to the user's room.
+
+ pthread_mutex_t mut_b_online;
+ pthread_mutex_t mut_i_sock;
+ pthread_mutex_t mut_l_time;
+ pthread_mutex_t mut_s_mess;
+ pthread_mutex_t mut_p_room;
+
+public:
+ pthread_cond_t cond_message;
+ pthread_mutex_t mut_message;
+
+ // small inline methods:
+ string get_col1() const { return s_col1; }
+ string get_id() const { return s_id; }
+ void set_id ( string s_id ) { this -> s_id = s_id; }
+ void set_col1 ( string s_col1 ) { this -> s_col1 = s_col1; }
+
+ rang get_rang ( ) const { return r_rang; }
+ void set_rang ( rang r_rang ) { r_oldr = this -> r_rang;
+ this -> r_rang = r_rang; }
+
+ bool new_msgs ( ) { return s_mess.empty(); }
+ // public methods:
+ explicit user( string s_name ); // a standard constructor.
+ ~user(); // user destructor.
+
+ // gets specific data of this user und stores it in
+ // (*p_map_string)["nick"]. this method will be used
+ // every time data has to be got from every user of a room
+ // or even of the system.
+ virtual void get_data( map_string *p_map_data );
+
+ virtual bool get_online();
+ virtual void set_online( bool b_online );
+ virtual room* get_p_room();
+ virtual void set_p_room( room* p_room );
+ virtual int get_sock ( );
+ virtual void set_sock ( int i_sock );
+
+ // executes a command.
+ virtual void command( string &s_command );
+
+ // gets the message and clears s_mess;
+ virtual string get_mess();
+
+ // actualizes the user's timestamp.
+ virtual void renew_stamp();
+
+ // Here are starting methods which are mainly needed by the data<type> class.
+
+ // appends a string to s_mess including br.
+ virtual void msg_post( string *p_msg );
+ virtual void get_user_list( string &s_list, string &s_seperator );
+};
+
+#endif
diff --git a/yChat-Perl-CGI/THIS_IS_LEGACY_SOFTWARE_AND_MIGHT_BE_BROKEN.txt b/yChat-Perl-CGI/THIS_IS_LEGACY_SOFTWARE_AND_MIGHT_BE_BROKEN.txt
new file mode 100644
index 0000000..ab645fa
--- /dev/null
+++ b/yChat-Perl-CGI/THIS_IS_LEGACY_SOFTWARE_AND_MIGHT_BE_BROKEN.txt
@@ -0,0 +1,2 @@
+This is legacy software and might be broken
+Please go to http://dev.buetow.org
diff --git a/yChat-Perl-CGI/ychat-0.2.1.zip b/yChat-Perl-CGI/ychat-0.2.1.zip
new file mode 100644
index 0000000..668bcd5
--- /dev/null
+++ b/yChat-Perl-CGI/ychat-0.2.1.zip
Binary files differ
diff --git a/yChat-Perl-CGI/ychat-0.2.2.zip b/yChat-Perl-CGI/ychat-0.2.2.zip
new file mode 100644
index 0000000..301bba9
--- /dev/null
+++ b/yChat-Perl-CGI/ychat-0.2.2.zip
Binary files differ
diff --git a/yChat-Perl-CGI/ychat-0.2.3.zip b/yChat-Perl-CGI/ychat-0.2.3.zip
new file mode 100644
index 0000000..2360c5a
--- /dev/null
+++ b/yChat-Perl-CGI/ychat-0.2.3.zip
Binary files differ
diff --git a/yChat-Perl-CGI/ychat-0.2.4a.zip b/yChat-Perl-CGI/ychat-0.2.4a.zip
new file mode 100644
index 0000000..88cf406
--- /dev/null
+++ b/yChat-Perl-CGI/ychat-0.2.4a.zip
Binary files differ
diff --git a/yChat-Perl-CGI/ychat-0.2.4c.zip b/yChat-Perl-CGI/ychat-0.2.4c.zip
new file mode 100644
index 0000000..ec5ebd7
--- /dev/null
+++ b/yChat-Perl-CGI/ychat-0.2.4c.zip
Binary files differ
diff --git a/yChat-Perl-CGI/ychat-0.2.5a2.zip b/yChat-Perl-CGI/ychat-0.2.5a2.zip
new file mode 100644
index 0000000..2d33ce8
--- /dev/null
+++ b/yChat-Perl-CGI/ychat-0.2.5a2.zip
Binary files differ
diff --git a/yChat-Perl-CGI/ychat-0.2.6a.zip b/yChat-Perl-CGI/ychat-0.2.6a.zip
new file mode 100644
index 0000000..0be2ac1
--- /dev/null
+++ b/yChat-Perl-CGI/ychat-0.2.6a.zip
Binary files differ
diff --git a/yChat-Perl-CGI/ychat-0.4.0a.zip b/yChat-Perl-CGI/ychat-0.4.0a.zip
new file mode 100644
index 0000000..6d3efb6
--- /dev/null
+++ b/yChat-Perl-CGI/ychat-0.4.0a.zip
Binary files differ
diff --git a/yChat-Perl-CGI/ychat-0.4.1.zip b/yChat-Perl-CGI/ychat-0.4.1.zip
new file mode 100644
index 0000000..49f6cb6
--- /dev/null
+++ b/yChat-Perl-CGI/ychat-0.4.1.zip
Binary files differ
diff --git a/yChat-Perl-CGI/ychat-0.4.2.zip b/yChat-Perl-CGI/ychat-0.4.2.zip
new file mode 100644
index 0000000..f5bd48e
--- /dev/null
+++ b/yChat-Perl-CGI/ychat-0.4.2.zip
Binary files differ
diff --git a/yChat-Perl-CGI/ychat-0.4.3a.zip b/yChat-Perl-CGI/ychat-0.4.3a.zip
new file mode 100644
index 0000000..7a6bdae
--- /dev/null
+++ b/yChat-Perl-CGI/ychat-0.4.3a.zip
Binary files differ
diff --git a/yChat-Perl-CGI/ychat-0.4.4a3.zip b/yChat-Perl-CGI/ychat-0.4.4a3.zip
new file mode 100644
index 0000000..21dd571
--- /dev/null
+++ b/yChat-Perl-CGI/ychat-0.4.4a3.zip
Binary files differ
diff --git a/yChat-Perl-CGI/ychat-0.4.5a.zip b/yChat-Perl-CGI/ychat-0.4.5a.zip
new file mode 100644
index 0000000..c281a1e
--- /dev/null
+++ b/yChat-Perl-CGI/ychat-0.4.5a.zip
Binary files differ
diff --git a/yChat-Perl-CGI/ychat-0.4.6.zip b/yChat-Perl-CGI/ychat-0.4.6.zip
new file mode 100644
index 0000000..d471c7a
--- /dev/null
+++ b/yChat-Perl-CGI/ychat-0.4.6.zip
Binary files differ
diff --git a/yChat-Perl-CGI/ychat-0.4.7a2.zip b/yChat-Perl-CGI/ychat-0.4.7a2.zip
new file mode 100644
index 0000000..cf4e944
--- /dev/null
+++ b/yChat-Perl-CGI/ychat-0.4.7a2.zip
Binary files differ
diff --git a/yChat-Perl-CGI/ychat-0.4.8a2.zip b/yChat-Perl-CGI/ychat-0.4.8a2.zip
new file mode 100644
index 0000000..8bc48a1
--- /dev/null
+++ b/yChat-Perl-CGI/ychat-0.4.8a2.zip
Binary files differ
diff --git a/yChat-Perl-CGI/ychat-0.4.9.zip b/yChat-Perl-CGI/ychat-0.4.9.zip
new file mode 100644
index 0000000..7d99926
--- /dev/null
+++ b/yChat-Perl-CGI/ychat-0.4.9.zip
Binary files differ
diff --git a/yChat-Perl-CGI/ychat-0.6.0.zip b/yChat-Perl-CGI/ychat-0.6.0.zip
new file mode 100644
index 0000000..36c8fa1
--- /dev/null
+++ b/yChat-Perl-CGI/ychat-0.6.0.zip
Binary files differ
diff --git a/yChat-Perl-CGI/ychat-0.6.1.zip b/yChat-Perl-CGI/ychat-0.6.1.zip
new file mode 100644
index 0000000..435a312
--- /dev/null
+++ b/yChat-Perl-CGI/ychat-0.6.1.zip
Binary files differ
diff --git a/yChat-Perl-CGI/ychat-0.6.2.zip b/yChat-Perl-CGI/ychat-0.6.2.zip
new file mode 100644
index 0000000..b1ef068
--- /dev/null
+++ b/yChat-Perl-CGI/ychat-0.6.2.zip
Binary files differ
diff --git a/yChat-Perl-Socket/THIS_IS_LEGACY_SOFTWARE_AND_MIGHT_BE_BROKEN.txt b/yChat-Perl-Socket/THIS_IS_LEGACY_SOFTWARE_AND_MIGHT_BE_BROKEN.txt
new file mode 100644
index 0000000..ab645fa
--- /dev/null
+++ b/yChat-Perl-Socket/THIS_IS_LEGACY_SOFTWARE_AND_MIGHT_BE_BROKEN.txt
@@ -0,0 +1,2 @@
+This is legacy software and might be broken
+Please go to http://dev.buetow.org
diff --git a/yChat-Perl-Socket/ychat-0.7.1.zip b/yChat-Perl-Socket/ychat-0.7.1.zip
new file mode 100644
index 0000000..021ddf1
--- /dev/null
+++ b/yChat-Perl-Socket/ychat-0.7.1.zip
Binary files differ
diff --git a/yChat-Perl-Socket/ychat-0.7.2.zip b/yChat-Perl-Socket/ychat-0.7.2.zip
new file mode 100644
index 0000000..dbeca25
--- /dev/null
+++ b/yChat-Perl-Socket/ychat-0.7.2.zip
Binary files differ
diff --git a/yChat-Perl-Socket/ychat-0.7.6.zip b/yChat-Perl-Socket/ychat-0.7.6.zip
new file mode 100644
index 0000000..7e677f3
--- /dev/null
+++ b/yChat-Perl-Socket/ychat-0.7.6.zip
Binary files differ
diff --git a/yChat-Perl-Socket/ychat-0.8.0.tar.gz b/yChat-Perl-Socket/ychat-0.8.0.tar.gz
new file mode 100644
index 0000000..5a342e1
--- /dev/null
+++ b/yChat-Perl-Socket/ychat-0.8.0.tar.gz
Binary files differ
diff --git a/yChat-Perl-Socket/ychat-0.8.1.tar.gz b/yChat-Perl-Socket/ychat-0.8.1.tar.gz
new file mode 100644
index 0000000..12ab26a
--- /dev/null
+++ b/yChat-Perl-Socket/ychat-0.8.1.tar.gz
Binary files differ
diff --git a/yChat/THIS_IS_LEGACY_SOFTWARE_AND_MIGHT_BE_BROKEN.txt b/yChat/THIS_IS_LEGACY_SOFTWARE_AND_MIGHT_BE_BROKEN.txt
new file mode 100644
index 0000000..ab645fa
--- /dev/null
+++ b/yChat/THIS_IS_LEGACY_SOFTWARE_AND_MIGHT_BE_BROKEN.txt
@@ -0,0 +1,2 @@
+This is legacy software and might be broken
+Please go to http://dev.buetow.org
diff --git a/yChat/desc/BRANCH_0_1 b/yChat/desc/BRANCH_0_1
new file mode 100644
index 0000000..af05e9b
--- /dev/null
+++ b/yChat/desc/BRANCH_0_1
@@ -0,0 +1 @@
+LEGACY
diff --git a/yChat/desc/BRANCH_0_2 b/yChat/desc/BRANCH_0_2
new file mode 100644
index 0000000..af05e9b
--- /dev/null
+++ b/yChat/desc/BRANCH_0_2
@@ -0,0 +1 @@
+LEGACY
diff --git a/yChat/desc/BRANCH_0_3 b/yChat/desc/BRANCH_0_3
new file mode 100644
index 0000000..af05e9b
--- /dev/null
+++ b/yChat/desc/BRANCH_0_3
@@ -0,0 +1 @@
+LEGACY
diff --git a/yChat/desc/BRANCH_0_4 b/yChat/desc/BRANCH_0_4
new file mode 100644
index 0000000..af05e9b
--- /dev/null
+++ b/yChat/desc/BRANCH_0_4
@@ -0,0 +1 @@
+LEGACY
diff --git a/yChat/desc/BRANCH_0_5 b/yChat/desc/BRANCH_0_5
new file mode 100644
index 0000000..af05e9b
--- /dev/null
+++ b/yChat/desc/BRANCH_0_5
@@ -0,0 +1 @@
+LEGACY
diff --git a/yChat/desc/BRANCH_0_6 b/yChat/desc/BRANCH_0_6
new file mode 100644
index 0000000..af05e9b
--- /dev/null
+++ b/yChat/desc/BRANCH_0_6
@@ -0,0 +1 @@
+LEGACY
diff --git a/yChat/desc/BRANCH_0_7 b/yChat/desc/BRANCH_0_7
new file mode 100644
index 0000000..6833df3
--- /dev/null
+++ b/yChat/desc/BRANCH_0_7
@@ -0,0 +1 @@
+STABLE
diff --git a/yChat/desc/BRANCH_0_8 b/yChat/desc/BRANCH_0_8
new file mode 100644
index 0000000..81785e9
--- /dev/null
+++ b/yChat/desc/BRANCH_0_8
@@ -0,0 +1 @@
+CURRENT
diff --git a/yChat/ychat-0.1.tar.bz2 b/yChat/ychat-0.1.tar.bz2
new file mode 100644
index 0000000..dbc7af2
--- /dev/null
+++ b/yChat/ychat-0.1.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.2.tar.bz2 b/yChat/ychat-0.2.tar.bz2
new file mode 100644
index 0000000..be294cd
--- /dev/null
+++ b/yChat/ychat-0.2.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.3.tar.bz2 b/yChat/ychat-0.3.tar.bz2
new file mode 100644
index 0000000..f0bd5eb
--- /dev/null
+++ b/yChat/ychat-0.3.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.4.tar.bz2 b/yChat/ychat-0.4.tar.bz2
new file mode 100644
index 0000000..c3465e2
--- /dev/null
+++ b/yChat/ychat-0.4.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.5.0.tar.bz2 b/yChat/ychat-0.5.0.tar.bz2
new file mode 100644
index 0000000..b61b69b
--- /dev/null
+++ b/yChat/ychat-0.5.0.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.5.1.tar.bz2 b/yChat/ychat-0.5.1.tar.bz2
new file mode 100644
index 0000000..d751996
--- /dev/null
+++ b/yChat/ychat-0.5.1.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.5.2.tar.bz2 b/yChat/ychat-0.5.2.tar.bz2
new file mode 100644
index 0000000..5b27a72
--- /dev/null
+++ b/yChat/ychat-0.5.2.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.5.3.tar.bz2 b/yChat/ychat-0.5.3.tar.bz2
new file mode 100644
index 0000000..13fcbea
--- /dev/null
+++ b/yChat/ychat-0.5.3.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.5.4.tar.bz2 b/yChat/ychat-0.5.4.tar.bz2
new file mode 100644
index 0000000..b094059
--- /dev/null
+++ b/yChat/ychat-0.5.4.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.5.5.tar.bz2 b/yChat/ychat-0.5.5.tar.bz2
new file mode 100644
index 0000000..b4d2d51
--- /dev/null
+++ b/yChat/ychat-0.5.5.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.6.0.tar.bz2 b/yChat/ychat-0.6.0.tar.bz2
new file mode 100644
index 0000000..832a3d4
--- /dev/null
+++ b/yChat/ychat-0.6.0.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.7.0.tar.bz2 b/yChat/ychat-0.7.0.tar.bz2
new file mode 100644
index 0000000..7050dd8
--- /dev/null
+++ b/yChat/ychat-0.7.0.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.7.1.tar.bz2 b/yChat/ychat-0.7.1.tar.bz2
new file mode 100644
index 0000000..ca9c6b3
--- /dev/null
+++ b/yChat/ychat-0.7.1.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.7.2.tar.bz2 b/yChat/ychat-0.7.2.tar.bz2
new file mode 100644
index 0000000..1a5e0e9
--- /dev/null
+++ b/yChat/ychat-0.7.2.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.7.3.tar.bz2 b/yChat/ychat-0.7.3.tar.bz2
new file mode 100644
index 0000000..5e3ed87
--- /dev/null
+++ b/yChat/ychat-0.7.3.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.7.4.1.tar.bz2 b/yChat/ychat-0.7.4.1.tar.bz2
new file mode 100644
index 0000000..25b3209
--- /dev/null
+++ b/yChat/ychat-0.7.4.1.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.7.5.tar.bz2 b/yChat/ychat-0.7.5.tar.bz2
new file mode 100644
index 0000000..6e4ff17
--- /dev/null
+++ b/yChat/ychat-0.7.5.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.7.6.tar.bz2 b/yChat/ychat-0.7.6.tar.bz2
new file mode 100644
index 0000000..da3306a
--- /dev/null
+++ b/yChat/ychat-0.7.6.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.7.7.0.tar.bz2 b/yChat/ychat-0.7.7.0.tar.bz2
new file mode 100644
index 0000000..931e0a6
--- /dev/null
+++ b/yChat/ychat-0.7.7.0.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.7.7.1.tar.bz2 b/yChat/ychat-0.7.7.1.tar.bz2
new file mode 100644
index 0000000..73b0436
--- /dev/null
+++ b/yChat/ychat-0.7.7.1.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.7.8.tar.bz2 b/yChat/ychat-0.7.8.tar.bz2
new file mode 100644
index 0000000..a93558c
--- /dev/null
+++ b/yChat/ychat-0.7.8.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.7.9.0.tar.bz2 b/yChat/ychat-0.7.9.0.tar.bz2
new file mode 100644
index 0000000..6b5924d
--- /dev/null
+++ b/yChat/ychat-0.7.9.0.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.7.9.1.tar.bz2 b/yChat/ychat-0.7.9.1.tar.bz2
new file mode 100644
index 0000000..c43e039
--- /dev/null
+++ b/yChat/ychat-0.7.9.1.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.7.9.2.tar.bz2 b/yChat/ychat-0.7.9.2.tar.bz2
new file mode 100644
index 0000000..d814bc1
--- /dev/null
+++ b/yChat/ychat-0.7.9.2.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.7.9.3.tar.bz2 b/yChat/ychat-0.7.9.3.tar.bz2
new file mode 100644
index 0000000..2d90570
--- /dev/null
+++ b/yChat/ychat-0.7.9.3.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.7.9.4.tar.bz2 b/yChat/ychat-0.7.9.4.tar.bz2
new file mode 100644
index 0000000..5e3de70
--- /dev/null
+++ b/yChat/ychat-0.7.9.4.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.7.9.5.tar.bz2 b/yChat/ychat-0.7.9.5.tar.bz2
new file mode 100644
index 0000000..6363f62
--- /dev/null
+++ b/yChat/ychat-0.7.9.5.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.8.0.tar.bz2 b/yChat/ychat-0.8.0.tar.bz2
new file mode 100644
index 0000000..827dac7
--- /dev/null
+++ b/yChat/ychat-0.8.0.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.8.1.tar.bz2 b/yChat/ychat-0.8.1.tar.bz2
new file mode 100644
index 0000000..b5184c3
--- /dev/null
+++ b/yChat/ychat-0.8.1.tar.bz2
Binary files differ
diff --git a/yChat/ychat-0.8.2.tar.bz2 b/yChat/ychat-0.8.2.tar.bz2
new file mode 100644
index 0000000..4723348
--- /dev/null
+++ b/yChat/ychat-0.8.2.tar.bz2
Binary files differ
diff --git a/yhttpd/IMPORTANT.txt b/yhttpd/IMPORTANT.txt
new file mode 100644
index 0000000..b559b9a
--- /dev/null
+++ b/yhttpd/IMPORTANT.txt
@@ -0,0 +1 @@
+Important notice: The development of the yhttpd has been stalled. There will be no further development on this project. This project always was a proof of concept only. For current programming projects please visit http://programming.buetow.org and enjoy :)
diff --git a/yhttpd/THIS_IS_LEGACY_SOFTWARE_AND_MIGHT_BE_BROKEN.txt b/yhttpd/THIS_IS_LEGACY_SOFTWARE_AND_MIGHT_BE_BROKEN.txt
new file mode 100644
index 0000000..ab645fa
--- /dev/null
+++ b/yhttpd/THIS_IS_LEGACY_SOFTWARE_AND_MIGHT_BE_BROKEN.txt
@@ -0,0 +1,2 @@
+This is legacy software and might be broken
+Please go to http://dev.buetow.org
diff --git a/yhttpd/desc/BRANCH_0_7 b/yhttpd/desc/BRANCH_0_7
new file mode 100644
index 0000000..6833df3
--- /dev/null
+++ b/yhttpd/desc/BRANCH_0_7
@@ -0,0 +1 @@
+STABLE
diff --git a/yhttpd/desc/BRANCH_0_8 b/yhttpd/desc/BRANCH_0_8
new file mode 100644
index 0000000..81785e9
--- /dev/null
+++ b/yhttpd/desc/BRANCH_0_8
@@ -0,0 +1 @@
+CURRENT
diff --git a/yhttpd/yhttpd-0.7.0.tar.bz2 b/yhttpd/yhttpd-0.7.0.tar.bz2
new file mode 100644
index 0000000..dbe88a5
--- /dev/null
+++ b/yhttpd/yhttpd-0.7.0.tar.bz2
Binary files differ
diff --git a/yhttpd/yhttpd-0.7.1.tar.bz2 b/yhttpd/yhttpd-0.7.1.tar.bz2
new file mode 100644
index 0000000..fffc979
--- /dev/null
+++ b/yhttpd/yhttpd-0.7.1.tar.bz2
Binary files differ
diff --git a/yhttpd/yhttpd-0.7.2.tar.bz2 b/yhttpd/yhttpd-0.7.2.tar.bz2
new file mode 100644
index 0000000..b23c618
--- /dev/null
+++ b/yhttpd/yhttpd-0.7.2.tar.bz2
Binary files differ