diff options
| -rw-r--r-- | ChangeLog | 484 | ||||
| -rw-r--r-- | Makefile.in | 12 | ||||
| -rw-r--r-- | base.cpp | 65 | ||||
| -rw-r--r-- | base.h | 71 | ||||
| -rw-r--r-- | chat.cpp | 147 | ||||
| -rw-r--r-- | chat.h | 46 | ||||
| -rw-r--r-- | cmnd.cpp | 19 | ||||
| -rw-r--r-- | cmnd.h | 18 | ||||
| -rw-r--r-- | conf.cpp | 75 | ||||
| -rw-r--r-- | conf.h | 24 | ||||
| -rw-r--r-- | configure.in | 28 | ||||
| -rw-r--r-- | cont.cpp | 24 | ||||
| -rw-r--r-- | cont.h | 26 | ||||
| -rw-r--r-- | glob.h | 68 | ||||
| -rw-r--r-- | hmap.cpp | 180 | ||||
| -rw-r--r-- | hmap.h | 118 | ||||
| -rw-r--r-- | html.cpp | 140 | ||||
| -rw-r--r-- | html.h | 42 | ||||
| -rw-r--r-- | html/y_ani.gif | bin | 0 -> 35107 bytes | |||
| -rw-r--r-- | incl.h | 16 | ||||
| -rw-r--r-- | lang.cpp | 78 | ||||
| -rw-r--r-- | lang.h | 24 | ||||
| -rw-r--r-- | logd.cpp | 65 | ||||
| -rw-r--r-- | logd.h | 24 | ||||
| -rw-r--r-- | main.cpp | 98 | ||||
| -rw-r--r-- | modl.cpp | 98 | ||||
| -rw-r--r-- | modl.h | 29 | ||||
| -rw-r--r-- | msgs.h | 36 | ||||
| -rw-r--r-- | mutx.cpp | 20 | ||||
| -rw-r--r-- | mutx.h | 21 | ||||
| -rw-r--r-- | name.cpp | 32 | ||||
| -rw-r--r-- | name.h | 28 | ||||
| -rw-r--r-- | pool.cpp | 214 | ||||
| -rw-r--r-- | pool.h | 77 | ||||
| -rw-r--r-- | reqp.cpp | 291 | ||||
| -rw-r--r-- | reqp.h | 47 | ||||
| -rw-r--r-- | room.cpp | 18 | ||||
| -rw-r--r-- | room.h | 34 | ||||
| -rw-r--r-- | s_chat.cpp | 10 | ||||
| -rw-r--r-- | s_chat.h | 26 | ||||
| -rw-r--r-- | s_conf.cpp | 10 | ||||
| -rw-r--r-- | s_conf.h | 26 | ||||
| -rw-r--r-- | s_html.cpp | 10 | ||||
| -rw-r--r-- | s_html.h | 26 | ||||
| -rw-r--r-- | s_lang.cpp | 10 | ||||
| -rw-r--r-- | s_lang.h | 26 | ||||
| -rw-r--r-- | s_modl.cpp | 10 | ||||
| -rw-r--r-- | s_modl.h | 26 | ||||
| -rw-r--r-- | s_mutx.cpp | 10 | ||||
| -rw-r--r-- | s_mutx.h | 26 | ||||
| -rw-r--r-- | s_sman.cpp | 10 | ||||
| -rw-r--r-- | s_sman.h | 26 | ||||
| -rw-r--r-- | s_sock.cpp | 10 | ||||
| -rw-r--r-- | s_sock.h | 26 | ||||
| -rw-r--r-- | s_tool.cpp | 111 | ||||
| -rw-r--r-- | s_tool.h | 19 | ||||
| -rw-r--r-- | sess.cpp | 35 | ||||
| -rw-r--r-- | sess.h | 28 | ||||
| -rw-r--r-- | sman.cpp | 48 | ||||
| -rw-r--r-- | sman.h | 32 | ||||
| -rw-r--r-- | sock.cpp | 238 | ||||
| -rw-r--r-- | sock.h | 53 | ||||
| -rw-r--r-- | thrd.cpp | 28 | ||||
| -rw-r--r-- | thrd.h | 26 | ||||
| -rw-r--r-- | todo.txt | 11 | ||||
| -rw-r--r-- | user.cpp | 170 | ||||
| -rw-r--r-- | user.h | 84 | ||||
| -rw-r--r-- | yChat-Perl-CGI/THIS_IS_LEGACY_SOFTWARE_AND_MIGHT_BE_BROKEN.txt | 2 | ||||
| -rw-r--r-- | yChat-Perl-CGI/ychat-0.2.1.zip | bin | 0 -> 72514 bytes | |||
| -rw-r--r-- | yChat-Perl-CGI/ychat-0.2.2.zip | bin | 0 -> 73682 bytes | |||
| -rw-r--r-- | yChat-Perl-CGI/ychat-0.2.3.zip | bin | 0 -> 80044 bytes | |||
| -rw-r--r-- | yChat-Perl-CGI/ychat-0.2.4a.zip | bin | 0 -> 81563 bytes | |||
| -rw-r--r-- | yChat-Perl-CGI/ychat-0.2.4c.zip | bin | 0 -> 81809 bytes | |||
| -rw-r--r-- | yChat-Perl-CGI/ychat-0.2.5a2.zip | bin | 0 -> 84947 bytes | |||
| -rw-r--r-- | yChat-Perl-CGI/ychat-0.2.6a.zip | bin | 0 -> 84715 bytes | |||
| -rw-r--r-- | yChat-Perl-CGI/ychat-0.4.0a.zip | bin | 0 -> 85353 bytes | |||
| -rw-r--r-- | yChat-Perl-CGI/ychat-0.4.1.zip | bin | 0 -> 87361 bytes | |||
| -rw-r--r-- | yChat-Perl-CGI/ychat-0.4.2.zip | bin | 0 -> 38558 bytes | |||
| -rw-r--r-- | yChat-Perl-CGI/ychat-0.4.3a.zip | bin | 0 -> 39762 bytes | |||
| -rw-r--r-- | yChat-Perl-CGI/ychat-0.4.4a3.zip | bin | 0 -> 41120 bytes | |||
| -rw-r--r-- | yChat-Perl-CGI/ychat-0.4.5a.zip | bin | 0 -> 54688 bytes | |||
| -rw-r--r-- | yChat-Perl-CGI/ychat-0.4.6.zip | bin | 0 -> 55180 bytes | |||
| -rw-r--r-- | yChat-Perl-CGI/ychat-0.4.7a2.zip | bin | 0 -> 58931 bytes | |||
| -rw-r--r-- | yChat-Perl-CGI/ychat-0.4.8a2.zip | bin | 0 -> 59105 bytes | |||
| -rw-r--r-- | yChat-Perl-CGI/ychat-0.4.9.zip | bin | 0 -> 64276 bytes | |||
| -rw-r--r-- | yChat-Perl-CGI/ychat-0.6.0.zip | bin | 0 -> 67379 bytes | |||
| -rw-r--r-- | yChat-Perl-CGI/ychat-0.6.1.zip | bin | 0 -> 66562 bytes | |||
| -rw-r--r-- | yChat-Perl-CGI/ychat-0.6.2.zip | bin | 0 -> 63478 bytes | |||
| -rw-r--r-- | yChat-Perl-Socket/THIS_IS_LEGACY_SOFTWARE_AND_MIGHT_BE_BROKEN.txt | 2 | ||||
| -rw-r--r-- | yChat-Perl-Socket/ychat-0.7.1.zip | bin | 0 -> 48438 bytes | |||
| -rw-r--r-- | yChat-Perl-Socket/ychat-0.7.2.zip | bin | 0 -> 40614 bytes | |||
| -rw-r--r-- | yChat-Perl-Socket/ychat-0.7.6.zip | bin | 0 -> 61017 bytes | |||
| -rw-r--r-- | yChat-Perl-Socket/ychat-0.8.0.tar.gz | bin | 0 -> 53873 bytes | |||
| -rw-r--r-- | yChat-Perl-Socket/ychat-0.8.1.tar.gz | bin | 0 -> 37632 bytes | |||
| -rw-r--r-- | yChat/THIS_IS_LEGACY_SOFTWARE_AND_MIGHT_BE_BROKEN.txt | 2 | ||||
| -rw-r--r-- | yChat/desc/BRANCH_0_1 | 1 | ||||
| -rw-r--r-- | yChat/desc/BRANCH_0_2 | 1 | ||||
| -rw-r--r-- | yChat/desc/BRANCH_0_3 | 1 | ||||
| -rw-r--r-- | yChat/desc/BRANCH_0_4 | 1 | ||||
| -rw-r--r-- | yChat/desc/BRANCH_0_5 | 1 | ||||
| -rw-r--r-- | yChat/desc/BRANCH_0_6 | 1 | ||||
| -rw-r--r-- | yChat/desc/BRANCH_0_7 | 1 | ||||
| -rw-r--r-- | yChat/desc/BRANCH_0_8 | 1 | ||||
| -rw-r--r-- | yChat/ychat-0.1.tar.bz2 | bin | 0 -> 170155 bytes | |||
| -rw-r--r-- | yChat/ychat-0.2.tar.bz2 | bin | 0 -> 171220 bytes | |||
| -rw-r--r-- | yChat/ychat-0.3.tar.bz2 | bin | 0 -> 216371 bytes | |||
| -rw-r--r-- | yChat/ychat-0.4.tar.bz2 | bin | 0 -> 220406 bytes | |||
| -rw-r--r-- | yChat/ychat-0.5.0.tar.bz2 | bin | 0 -> 145903 bytes | |||
| -rw-r--r-- | yChat/ychat-0.5.1.tar.bz2 | bin | 0 -> 148333 bytes | |||
| -rw-r--r-- | yChat/ychat-0.5.2.tar.bz2 | bin | 0 -> 221718 bytes | |||
| -rw-r--r-- | yChat/ychat-0.5.3.tar.bz2 | bin | 0 -> 145031 bytes | |||
| -rw-r--r-- | yChat/ychat-0.5.4.tar.bz2 | bin | 0 -> 144531 bytes | |||
| -rw-r--r-- | yChat/ychat-0.5.5.tar.bz2 | bin | 0 -> 110132 bytes | |||
| -rw-r--r-- | yChat/ychat-0.6.0.tar.bz2 | bin | 0 -> 153809 bytes | |||
| -rw-r--r-- | yChat/ychat-0.7.0.tar.bz2 | bin | 0 -> 124127 bytes | |||
| -rw-r--r-- | yChat/ychat-0.7.1.tar.bz2 | bin | 0 -> 125087 bytes | |||
| -rw-r--r-- | yChat/ychat-0.7.2.tar.bz2 | bin | 0 -> 113640 bytes | |||
| -rw-r--r-- | yChat/ychat-0.7.3.tar.bz2 | bin | 0 -> 114017 bytes | |||
| -rw-r--r-- | yChat/ychat-0.7.4.1.tar.bz2 | bin | 0 -> 113726 bytes | |||
| -rw-r--r-- | yChat/ychat-0.7.5.tar.bz2 | bin | 0 -> 116694 bytes | |||
| -rw-r--r-- | yChat/ychat-0.7.6.tar.bz2 | bin | 0 -> 115702 bytes | |||
| -rw-r--r-- | yChat/ychat-0.7.7.0.tar.bz2 | bin | 0 -> 113976 bytes | |||
| -rw-r--r-- | yChat/ychat-0.7.7.1.tar.bz2 | bin | 0 -> 113780 bytes | |||
| -rw-r--r-- | yChat/ychat-0.7.8.tar.bz2 | bin | 0 -> 116917 bytes | |||
| -rw-r--r-- | yChat/ychat-0.7.9.0.tar.bz2 | bin | 0 -> 119470 bytes | |||
| -rw-r--r-- | yChat/ychat-0.7.9.1.tar.bz2 | bin | 0 -> 117002 bytes | |||
| -rw-r--r-- | yChat/ychat-0.7.9.2.tar.bz2 | bin | 0 -> 116239 bytes | |||
| -rw-r--r-- | yChat/ychat-0.7.9.3.tar.bz2 | bin | 0 -> 111797 bytes | |||
| -rw-r--r-- | yChat/ychat-0.7.9.4.tar.bz2 | bin | 0 -> 111917 bytes | |||
| -rw-r--r-- | yChat/ychat-0.7.9.5.tar.bz2 | bin | 0 -> 113717 bytes | |||
| -rw-r--r-- | yChat/ychat-0.8.0.tar.bz2 | bin | 0 -> 119501 bytes | |||
| -rw-r--r-- | yChat/ychat-0.8.1.tar.bz2 | bin | 0 -> 120381 bytes | |||
| -rw-r--r-- | yChat/ychat-0.8.2.tar.bz2 | bin | 0 -> 122336 bytes | |||
| -rw-r--r-- | yhttpd/IMPORTANT.txt | 1 | ||||
| -rw-r--r-- | yhttpd/THIS_IS_LEGACY_SOFTWARE_AND_MIGHT_BE_BROKEN.txt | 2 | ||||
| -rw-r--r-- | yhttpd/desc/BRANCH_0_7 | 1 | ||||
| -rw-r--r-- | yhttpd/desc/BRANCH_0_8 | 1 | ||||
| -rw-r--r-- | yhttpd/yhttpd-0.7.0.tar.bz2 | bin | 0 -> 192570 bytes | |||
| -rw-r--r-- | yhttpd/yhttpd-0.7.1.tar.bz2 | bin | 0 -> 194129 bytes | |||
| -rw-r--r-- | yhttpd/yhttpd-0.7.2.tar.bz2 | bin | 0 -> 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 @@ -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*)¶m ); + + 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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 + @@ -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 + @@ -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 Binary files differnew file mode 100644 index 0000000..e730988 --- /dev/null +++ b/html/y_ani.gif @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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,"<"); + + 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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 Binary files differnew file mode 100644 index 0000000..668bcd5 --- /dev/null +++ b/yChat-Perl-CGI/ychat-0.2.1.zip diff --git a/yChat-Perl-CGI/ychat-0.2.2.zip b/yChat-Perl-CGI/ychat-0.2.2.zip Binary files differnew file mode 100644 index 0000000..301bba9 --- /dev/null +++ b/yChat-Perl-CGI/ychat-0.2.2.zip diff --git a/yChat-Perl-CGI/ychat-0.2.3.zip b/yChat-Perl-CGI/ychat-0.2.3.zip Binary files differnew file mode 100644 index 0000000..2360c5a --- /dev/null +++ b/yChat-Perl-CGI/ychat-0.2.3.zip diff --git a/yChat-Perl-CGI/ychat-0.2.4a.zip b/yChat-Perl-CGI/ychat-0.2.4a.zip Binary files differnew file mode 100644 index 0000000..88cf406 --- /dev/null +++ b/yChat-Perl-CGI/ychat-0.2.4a.zip diff --git a/yChat-Perl-CGI/ychat-0.2.4c.zip b/yChat-Perl-CGI/ychat-0.2.4c.zip Binary files differnew file mode 100644 index 0000000..ec5ebd7 --- /dev/null +++ b/yChat-Perl-CGI/ychat-0.2.4c.zip diff --git a/yChat-Perl-CGI/ychat-0.2.5a2.zip b/yChat-Perl-CGI/ychat-0.2.5a2.zip Binary files differnew file mode 100644 index 0000000..2d33ce8 --- /dev/null +++ b/yChat-Perl-CGI/ychat-0.2.5a2.zip diff --git a/yChat-Perl-CGI/ychat-0.2.6a.zip b/yChat-Perl-CGI/ychat-0.2.6a.zip Binary files differnew file mode 100644 index 0000000..0be2ac1 --- /dev/null +++ b/yChat-Perl-CGI/ychat-0.2.6a.zip diff --git a/yChat-Perl-CGI/ychat-0.4.0a.zip b/yChat-Perl-CGI/ychat-0.4.0a.zip Binary files differnew file mode 100644 index 0000000..6d3efb6 --- /dev/null +++ b/yChat-Perl-CGI/ychat-0.4.0a.zip diff --git a/yChat-Perl-CGI/ychat-0.4.1.zip b/yChat-Perl-CGI/ychat-0.4.1.zip Binary files differnew file mode 100644 index 0000000..49f6cb6 --- /dev/null +++ b/yChat-Perl-CGI/ychat-0.4.1.zip diff --git a/yChat-Perl-CGI/ychat-0.4.2.zip b/yChat-Perl-CGI/ychat-0.4.2.zip Binary files differnew file mode 100644 index 0000000..f5bd48e --- /dev/null +++ b/yChat-Perl-CGI/ychat-0.4.2.zip diff --git a/yChat-Perl-CGI/ychat-0.4.3a.zip b/yChat-Perl-CGI/ychat-0.4.3a.zip Binary files differnew file mode 100644 index 0000000..7a6bdae --- /dev/null +++ b/yChat-Perl-CGI/ychat-0.4.3a.zip diff --git a/yChat-Perl-CGI/ychat-0.4.4a3.zip b/yChat-Perl-CGI/ychat-0.4.4a3.zip Binary files differnew file mode 100644 index 0000000..21dd571 --- /dev/null +++ b/yChat-Perl-CGI/ychat-0.4.4a3.zip diff --git a/yChat-Perl-CGI/ychat-0.4.5a.zip b/yChat-Perl-CGI/ychat-0.4.5a.zip Binary files differnew file mode 100644 index 0000000..c281a1e --- /dev/null +++ b/yChat-Perl-CGI/ychat-0.4.5a.zip diff --git a/yChat-Perl-CGI/ychat-0.4.6.zip b/yChat-Perl-CGI/ychat-0.4.6.zip Binary files differnew file mode 100644 index 0000000..d471c7a --- /dev/null +++ b/yChat-Perl-CGI/ychat-0.4.6.zip diff --git a/yChat-Perl-CGI/ychat-0.4.7a2.zip b/yChat-Perl-CGI/ychat-0.4.7a2.zip Binary files differnew file mode 100644 index 0000000..cf4e944 --- /dev/null +++ b/yChat-Perl-CGI/ychat-0.4.7a2.zip diff --git a/yChat-Perl-CGI/ychat-0.4.8a2.zip b/yChat-Perl-CGI/ychat-0.4.8a2.zip Binary files differnew file mode 100644 index 0000000..8bc48a1 --- /dev/null +++ b/yChat-Perl-CGI/ychat-0.4.8a2.zip diff --git a/yChat-Perl-CGI/ychat-0.4.9.zip b/yChat-Perl-CGI/ychat-0.4.9.zip Binary files differnew file mode 100644 index 0000000..7d99926 --- /dev/null +++ b/yChat-Perl-CGI/ychat-0.4.9.zip diff --git a/yChat-Perl-CGI/ychat-0.6.0.zip b/yChat-Perl-CGI/ychat-0.6.0.zip Binary files differnew file mode 100644 index 0000000..36c8fa1 --- /dev/null +++ b/yChat-Perl-CGI/ychat-0.6.0.zip diff --git a/yChat-Perl-CGI/ychat-0.6.1.zip b/yChat-Perl-CGI/ychat-0.6.1.zip Binary files differnew file mode 100644 index 0000000..435a312 --- /dev/null +++ b/yChat-Perl-CGI/ychat-0.6.1.zip diff --git a/yChat-Perl-CGI/ychat-0.6.2.zip b/yChat-Perl-CGI/ychat-0.6.2.zip Binary files differnew file mode 100644 index 0000000..b1ef068 --- /dev/null +++ b/yChat-Perl-CGI/ychat-0.6.2.zip 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 Binary files differnew file mode 100644 index 0000000..021ddf1 --- /dev/null +++ b/yChat-Perl-Socket/ychat-0.7.1.zip diff --git a/yChat-Perl-Socket/ychat-0.7.2.zip b/yChat-Perl-Socket/ychat-0.7.2.zip Binary files differnew file mode 100644 index 0000000..dbeca25 --- /dev/null +++ b/yChat-Perl-Socket/ychat-0.7.2.zip diff --git a/yChat-Perl-Socket/ychat-0.7.6.zip b/yChat-Perl-Socket/ychat-0.7.6.zip Binary files differnew file mode 100644 index 0000000..7e677f3 --- /dev/null +++ b/yChat-Perl-Socket/ychat-0.7.6.zip diff --git a/yChat-Perl-Socket/ychat-0.8.0.tar.gz b/yChat-Perl-Socket/ychat-0.8.0.tar.gz Binary files differnew file mode 100644 index 0000000..5a342e1 --- /dev/null +++ b/yChat-Perl-Socket/ychat-0.8.0.tar.gz diff --git a/yChat-Perl-Socket/ychat-0.8.1.tar.gz b/yChat-Perl-Socket/ychat-0.8.1.tar.gz Binary files differnew file mode 100644 index 0000000..12ab26a --- /dev/null +++ b/yChat-Perl-Socket/ychat-0.8.1.tar.gz 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 Binary files differnew file mode 100644 index 0000000..dbc7af2 --- /dev/null +++ b/yChat/ychat-0.1.tar.bz2 diff --git a/yChat/ychat-0.2.tar.bz2 b/yChat/ychat-0.2.tar.bz2 Binary files differnew file mode 100644 index 0000000..be294cd --- /dev/null +++ b/yChat/ychat-0.2.tar.bz2 diff --git a/yChat/ychat-0.3.tar.bz2 b/yChat/ychat-0.3.tar.bz2 Binary files differnew file mode 100644 index 0000000..f0bd5eb --- /dev/null +++ b/yChat/ychat-0.3.tar.bz2 diff --git a/yChat/ychat-0.4.tar.bz2 b/yChat/ychat-0.4.tar.bz2 Binary files differnew file mode 100644 index 0000000..c3465e2 --- /dev/null +++ b/yChat/ychat-0.4.tar.bz2 diff --git a/yChat/ychat-0.5.0.tar.bz2 b/yChat/ychat-0.5.0.tar.bz2 Binary files differnew file mode 100644 index 0000000..b61b69b --- /dev/null +++ b/yChat/ychat-0.5.0.tar.bz2 diff --git a/yChat/ychat-0.5.1.tar.bz2 b/yChat/ychat-0.5.1.tar.bz2 Binary files differnew file mode 100644 index 0000000..d751996 --- /dev/null +++ b/yChat/ychat-0.5.1.tar.bz2 diff --git a/yChat/ychat-0.5.2.tar.bz2 b/yChat/ychat-0.5.2.tar.bz2 Binary files differnew file mode 100644 index 0000000..5b27a72 --- /dev/null +++ b/yChat/ychat-0.5.2.tar.bz2 diff --git a/yChat/ychat-0.5.3.tar.bz2 b/yChat/ychat-0.5.3.tar.bz2 Binary files differnew file mode 100644 index 0000000..13fcbea --- /dev/null +++ b/yChat/ychat-0.5.3.tar.bz2 diff --git a/yChat/ychat-0.5.4.tar.bz2 b/yChat/ychat-0.5.4.tar.bz2 Binary files differnew file mode 100644 index 0000000..b094059 --- /dev/null +++ b/yChat/ychat-0.5.4.tar.bz2 diff --git a/yChat/ychat-0.5.5.tar.bz2 b/yChat/ychat-0.5.5.tar.bz2 Binary files differnew file mode 100644 index 0000000..b4d2d51 --- /dev/null +++ b/yChat/ychat-0.5.5.tar.bz2 diff --git a/yChat/ychat-0.6.0.tar.bz2 b/yChat/ychat-0.6.0.tar.bz2 Binary files differnew file mode 100644 index 0000000..832a3d4 --- /dev/null +++ b/yChat/ychat-0.6.0.tar.bz2 diff --git a/yChat/ychat-0.7.0.tar.bz2 b/yChat/ychat-0.7.0.tar.bz2 Binary files differnew file mode 100644 index 0000000..7050dd8 --- /dev/null +++ b/yChat/ychat-0.7.0.tar.bz2 diff --git a/yChat/ychat-0.7.1.tar.bz2 b/yChat/ychat-0.7.1.tar.bz2 Binary files differnew file mode 100644 index 0000000..ca9c6b3 --- /dev/null +++ b/yChat/ychat-0.7.1.tar.bz2 diff --git a/yChat/ychat-0.7.2.tar.bz2 b/yChat/ychat-0.7.2.tar.bz2 Binary files differnew file mode 100644 index 0000000..1a5e0e9 --- /dev/null +++ b/yChat/ychat-0.7.2.tar.bz2 diff --git a/yChat/ychat-0.7.3.tar.bz2 b/yChat/ychat-0.7.3.tar.bz2 Binary files differnew file mode 100644 index 0000000..5e3ed87 --- /dev/null +++ b/yChat/ychat-0.7.3.tar.bz2 diff --git a/yChat/ychat-0.7.4.1.tar.bz2 b/yChat/ychat-0.7.4.1.tar.bz2 Binary files differnew file mode 100644 index 0000000..25b3209 --- /dev/null +++ b/yChat/ychat-0.7.4.1.tar.bz2 diff --git a/yChat/ychat-0.7.5.tar.bz2 b/yChat/ychat-0.7.5.tar.bz2 Binary files differnew file mode 100644 index 0000000..6e4ff17 --- /dev/null +++ b/yChat/ychat-0.7.5.tar.bz2 diff --git a/yChat/ychat-0.7.6.tar.bz2 b/yChat/ychat-0.7.6.tar.bz2 Binary files differnew file mode 100644 index 0000000..da3306a --- /dev/null +++ b/yChat/ychat-0.7.6.tar.bz2 diff --git a/yChat/ychat-0.7.7.0.tar.bz2 b/yChat/ychat-0.7.7.0.tar.bz2 Binary files differnew file mode 100644 index 0000000..931e0a6 --- /dev/null +++ b/yChat/ychat-0.7.7.0.tar.bz2 diff --git a/yChat/ychat-0.7.7.1.tar.bz2 b/yChat/ychat-0.7.7.1.tar.bz2 Binary files differnew file mode 100644 index 0000000..73b0436 --- /dev/null +++ b/yChat/ychat-0.7.7.1.tar.bz2 diff --git a/yChat/ychat-0.7.8.tar.bz2 b/yChat/ychat-0.7.8.tar.bz2 Binary files differnew file mode 100644 index 0000000..a93558c --- /dev/null +++ b/yChat/ychat-0.7.8.tar.bz2 diff --git a/yChat/ychat-0.7.9.0.tar.bz2 b/yChat/ychat-0.7.9.0.tar.bz2 Binary files differnew file mode 100644 index 0000000..6b5924d --- /dev/null +++ b/yChat/ychat-0.7.9.0.tar.bz2 diff --git a/yChat/ychat-0.7.9.1.tar.bz2 b/yChat/ychat-0.7.9.1.tar.bz2 Binary files differnew file mode 100644 index 0000000..c43e039 --- /dev/null +++ b/yChat/ychat-0.7.9.1.tar.bz2 diff --git a/yChat/ychat-0.7.9.2.tar.bz2 b/yChat/ychat-0.7.9.2.tar.bz2 Binary files differnew file mode 100644 index 0000000..d814bc1 --- /dev/null +++ b/yChat/ychat-0.7.9.2.tar.bz2 diff --git a/yChat/ychat-0.7.9.3.tar.bz2 b/yChat/ychat-0.7.9.3.tar.bz2 Binary files differnew file mode 100644 index 0000000..2d90570 --- /dev/null +++ b/yChat/ychat-0.7.9.3.tar.bz2 diff --git a/yChat/ychat-0.7.9.4.tar.bz2 b/yChat/ychat-0.7.9.4.tar.bz2 Binary files differnew file mode 100644 index 0000000..5e3de70 --- /dev/null +++ b/yChat/ychat-0.7.9.4.tar.bz2 diff --git a/yChat/ychat-0.7.9.5.tar.bz2 b/yChat/ychat-0.7.9.5.tar.bz2 Binary files differnew file mode 100644 index 0000000..6363f62 --- /dev/null +++ b/yChat/ychat-0.7.9.5.tar.bz2 diff --git a/yChat/ychat-0.8.0.tar.bz2 b/yChat/ychat-0.8.0.tar.bz2 Binary files differnew file mode 100644 index 0000000..827dac7 --- /dev/null +++ b/yChat/ychat-0.8.0.tar.bz2 diff --git a/yChat/ychat-0.8.1.tar.bz2 b/yChat/ychat-0.8.1.tar.bz2 Binary files differnew file mode 100644 index 0000000..b5184c3 --- /dev/null +++ b/yChat/ychat-0.8.1.tar.bz2 diff --git a/yChat/ychat-0.8.2.tar.bz2 b/yChat/ychat-0.8.2.tar.bz2 Binary files differnew file mode 100644 index 0000000..4723348 --- /dev/null +++ b/yChat/ychat-0.8.2.tar.bz2 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 Binary files differnew file mode 100644 index 0000000..dbe88a5 --- /dev/null +++ b/yhttpd/yhttpd-0.7.0.tar.bz2 diff --git a/yhttpd/yhttpd-0.7.1.tar.bz2 b/yhttpd/yhttpd-0.7.1.tar.bz2 Binary files differnew file mode 100644 index 0000000..fffc979 --- /dev/null +++ b/yhttpd/yhttpd-0.7.1.tar.bz2 diff --git a/yhttpd/yhttpd-0.7.2.tar.bz2 b/yhttpd/yhttpd-0.7.2.tar.bz2 Binary files differnew file mode 100644 index 0000000..b23c618 --- /dev/null +++ b/yhttpd/yhttpd-0.7.2.tar.bz2 |
