diff options
| author | Paul Buetow <paul@buetow.org> | 2013-04-06 13:14:45 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2013-04-06 13:14:45 +0200 |
| commit | 23c5e7d57e1e9216f4da3446656df2dc7202975d (patch) | |
| tree | b387afc4ad6acad4681252df8ce8def5dc8aa54d | |
| parent | 9dcec1feba68dc5ba38cdc634f5bf113c0f77348 (diff) | |
tagging ychat-0.1ychat-0.1
| -rw-r--r-- | CHAT.cpp | 10 | ||||
| -rw-r--r-- | CHAT.h | 26 | ||||
| -rw-r--r-- | CONF.cpp | 10 | ||||
| -rw-r--r-- | CONF.h | 26 | ||||
| -rw-r--r-- | HTML.cpp | 10 | ||||
| -rw-r--r-- | HTML.h | 26 | ||||
| -rw-r--r-- | MUTX.cpp | 10 | ||||
| -rw-r--r-- | MUTX.h | 26 | ||||
| -rw-r--r--[-rwxr-xr-x] | Makefile | 95 | ||||
| -rw-r--r-- | README.txt | 169 | ||||
| -rw-r--r-- | SOCK.cpp | 10 | ||||
| -rw-r--r-- | SOCK.h | 26 | ||||
| -rw-r--r-- | TOOL.cpp | 33 | ||||
| -rw-r--r-- | TOOL.h | 15 | ||||
| -rw-r--r--[-rwxr-xr-x] | base.cpp | 134 | ||||
| -rw-r--r--[-rwxr-xr-x] | base.h | 60 | ||||
| -rw-r--r--[-rwxr-xr-x] | chat.cpp | 95 | ||||
| -rw-r--r--[-rwxr-xr-x] | chat.h | 9 | ||||
| -rw-r--r--[-rwxr-xr-x] | cmnd.cpp | 12 | ||||
| -rw-r--r--[-rwxr-xr-x] | cmnd.h | 0 | ||||
| -rw-r--r--[-rwxr-xr-x] | conf.cpp | 20 | ||||
| -rw-r--r--[-rwxr-xr-x] | conf.h | 4 | ||||
| -rw-r--r--[-rwxr-xr-x] | conf.txt | 49 | ||||
| -rw-r--r--[-rwxr-xr-x] | cont.cpp | 13 | ||||
| -rw-r--r--[-rwxr-xr-x] | cont.h | 1 | ||||
| -rw-r--r-- | data.h | 62 | ||||
| -rw-r--r--[-rwxr-xr-x] | gfx/y_ani_black.gif | bin | 61100 -> 61100 bytes | |||
| -rw-r--r--[-rwxr-xr-x] | gfx/y_ani_white.gif | bin | 53536 -> 53536 bytes | |||
| -rw-r--r--[-rwxr-xr-x] | glob.h | 14 | ||||
| -rw-r--r--[-rwxr-xr-x] | html.cpp | 65 | ||||
| -rw-r--r--[-rwxr-xr-x] | html.h | 7 | ||||
| -rw-r--r--[-rwxr-xr-x] | html/blank.html | 0 | ||||
| -rw-r--r--[-rwxr-xr-x] | html/frameset.html | 0 | ||||
| -rw-r--r--[-rwxr-xr-x] | html/index.html | 44 | ||||
| -rw-r--r--[-rwxr-xr-x] | html/input.html | 4 | ||||
| -rw-r--r--[-rwxr-xr-x] | html/notfound.html | 4 | ||||
| -rw-r--r--[-rwxr-xr-x] | html/online.html | 3 | ||||
| -rw-r--r--[-rwxr-xr-x] | html/stream.html | 3 | ||||
| -rw-r--r--[-rwxr-xr-x] | html/y_ani.gif | bin | 35107 -> 35107 bytes | |||
| -rw-r--r--[-rwxr-xr-x] | incl.h | 1 | ||||
| -rw-r--r--[-rwxr-xr-x] | main.cpp | 40 | ||||
| -rw-r--r--[-rwxr-xr-x] | msgs.h | 20 | ||||
| -rw-r--r--[-rwxr-xr-x] | mutx.cpp | 12 | ||||
| -rw-r--r--[-rwxr-xr-x] | mutx.h | 4 | ||||
| -rw-r--r--[-rwxr-xr-x] | name.cpp | 26 | ||||
| -rw-r--r--[-rwxr-xr-x] | name.h | 4 | ||||
| -rw-r--r--[-rwxr-xr-x] | reqp.cpp | 199 | ||||
| -rw-r--r--[-rwxr-xr-x] | reqp.h | 12 | ||||
| -rw-r--r--[-rwxr-xr-x] | room.cpp | 11 | ||||
| -rw-r--r--[-rwxr-xr-x] | room.h | 4 | ||||
| -rw-r--r--[-rwxr-xr-x] | sock.cpp | 196 | ||||
| -rw-r--r--[-rwxr-xr-x] | sock.h | 26 | ||||
| -rw-r--r--[-rwxr-xr-x] | thrd.cpp | 24 | ||||
| -rw-r--r--[-rwxr-xr-x] | thrd.h | 0 | ||||
| -rw-r--r--[-rwxr-xr-x] | todo.txt | 14 | ||||
| -rw-r--r--[-rwxr-xr-x] | user.cpp | 108 | ||||
| -rw-r--r--[-rwxr-xr-x] | user.h | 13 |
57 files changed, 1194 insertions, 615 deletions
diff --git a/CHAT.cpp b/CHAT.cpp new file mode 100644 index 0000000..1358a06 --- /dev/null +++ b/CHAT.cpp @@ -0,0 +1,10 @@ +#ifndef GCHT_CXX +#define GCHT_CXX + +#include "CHAT.h" + +using namespace std; + +chat* CHAT::obj; + +#endif @@ -0,0 +1,26 @@ +#ifndef GCHT_H +#define GCHT_H + +#include "chat.h" + +using namespace std; + +class CHAT +{ +private: + static chat* obj; + +public: + static void init() + { + obj = new chat(); + } + + static chat& get() + { + return *obj; + } +}; + + +#endif diff --git a/CONF.cpp b/CONF.cpp new file mode 100644 index 0000000..8b5441c --- /dev/null +++ b/CONF.cpp @@ -0,0 +1,10 @@ +#ifndef GCON_CXX +#define GCON_CXX + +#include "CONF.h" + +using namespace std; + +conf* CONF::obj; + +#endif @@ -0,0 +1,26 @@ +#ifndef GCON_H +#define GCON_H + +#include "conf.h" + +using namespace std; + +class CONF +{ +private: + static conf* obj; + +public: + static void init() + { + obj = new conf( CONFILE ); + } + + static conf& get() + { + return *obj; + } +}; + + +#endif diff --git a/HTML.cpp b/HTML.cpp new file mode 100644 index 0000000..a93bc0a --- /dev/null +++ b/HTML.cpp @@ -0,0 +1,10 @@ +#ifndef GHTM_CXX +#define GHTM_CXX + +#include "HTML.h" + +using namespace std; + +html* HTML::obj; + +#endif @@ -0,0 +1,26 @@ +#ifndef GHTM_H +#define GHTM_H + +#include "html.h" + +using namespace std; + +class HTML +{ +private: + static html* obj; + +public: + static void init() + { + obj = new html(); + } + + static html& get() + { + return *obj; + } +}; + + +#endif diff --git a/MUTX.cpp b/MUTX.cpp new file mode 100644 index 0000000..41382f3 --- /dev/null +++ b/MUTX.cpp @@ -0,0 +1,10 @@ +#ifndef GMUT_CXX +#define GMUT_CXX + +#include "MUTX.h" + +using namespace std; + +mutx* MUTX::obj; + +#endif @@ -0,0 +1,26 @@ +#ifndef GMUT_H +#define GMUT_H + +#include "mutx.h" + +using namespace std; + +class MUTX +{ +private: + static mutx* obj; + +public: + static void init() + { + obj = new mutx(); + } + + static mutx& get() + { + return *obj; + } +}; + + +#endif @@ -1,83 +1,12 @@ -MAKE=`tail -n 1 make.version` -PREFIX=`grep "define PREFIX" src/glob.h | cut -d'"' -f2` -all: version base modules - @echo "Now edit the yhttpd.conf and run yhttpd!" - @echo "The config file is searched in the following order:" - @echo " ./yhttpd.conf " - @echo " ~/.yhttpd/yhttpd.conf " - @echo " ./etc/yhttpd.conf " - @echo " /etc/yhttpd.conf " - @echo " $(PREFIX)/etc/yhttpd.conf " - @echo If you want to help the yhttpd project please run gmake mail - @echo so that the developers receive an email about the platform - @echo being used. - @echo WARNING! This software is EXPERIMENTAL! -mail: - @echo "VERSION:" > mail.tmp - @${MAKE} version >> mail.tmp - @echo >> mail.tmp - @echo "UNAME:" >> mail.tmp - @uname -a >> mail.tmp - @echo >> mail.tmp - @echo "DATE:" >> mail.tmp - @date >> mail.tmp - @echo >> mail.tmp - @echo "COMPILER AND MAKE:" >> mail.tmp - @cat g++.version make.version >> mail.tmp - @cat mail.tmp | mail -s "Successfull build of yhttpd" successfullbuild@yChat.org - @rm -f mail.tmp -install: deinstall -uninstall: deinstall -deinstall: - @echo Install/deinstall is not supported! - @echo Start yhttpd with ./bin/yhttpd instead! - @exit 1 -modules: - @if test -d ./src/mods; then ${MAKE} -C ./src/mods; fi -clean_modules: - @if test -d ./src/mods; then ${MAKE} -C ./src/mods clean; fi -base: - @if test -f bin/yhttpd; then echo "Backing up old binary";if test -f bin/yhttpd.old; then rm -f bin/yhttpd.old; fi; mv bin/yhttpd bin/yhttpd.old; fi - @perl ./scripts/buildnr.pl - @perl ./scripts/setglobvals.pl - @${MAKE} -C ./src -clean_base: - @${MAKE} -C ./src clean -stats: - @perl scripts/stats.pl -run: - ./bin/yhttpd -base_start: base - ./bin/yhttpd -gpl: - @more COPYING -clean: clean_base clean_modules -help: - @echo "You may run ${MAKE} with the following parameters:" - @grep "^ ${MAKE} " README - @echo "For more questions read the README file or contact mail@yChat.org!" -setup: - @./configure - @${MAKE} -config: - @sh -c "scripts/config.sh" - @echo If you run ${MAKE} config from the command line then you may need - @echo to rerun ./configure and recompile all now! - -mrproper: clean - @if test -f src/glob.h.org; then mv -f src/glob.h.org src/glob.h;fi - @if test -f g++.version; then rm -f g++.version; fi - @if test -f make.version; then rm -f make.version; fi - @if test -f src/Makefile; then rm -f src/Makefile; fi - @if test -f bin/yhttpd; then find bin/ -name "*yhttpd*" | xargs rm -f; fi - @if test -d src/mods; then find src/mods/*/ -name Makefile | xargs rm -f; fi - @find . -name "*.add" | xargs rm -f - @ls | grep core | xargs rm -f -version: - @./scripts/version.sh -debug: - @gdb bin/yhttpd yhttpd.core -confdebug: - ./configure -g3 -ggdb -dist: - @./scripts/makedist.sh +SRCS=base.cpp chat.cpp CHAT.cpp cmnd.cpp conf.cpp CONF.cpp cont.cpp html.cpp HTML.cpp main.cpp mutx.cpp MUTX.cpp name.cpp reqp.cpp room.cpp sock.cpp SOCK.cpp thrd.cpp TOOL.cpp user.cpp +OBJS=$(SRCS:.cpp=.o) +CC=c++ +LDFLAGS=-lstdc++ +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/README.txt b/README.txt new file mode 100644 index 0000000..e68c165 --- /dev/null +++ b/README.txt @@ -0,0 +1,169 @@ +yChat++; Version Basic 0.1b (030320); Homepage: www.yChat.org +Copyright (C) 2003 Paul C. Buetow ( Snooper@yChat.org, ICQ: 11655527 ) +----------------------------------------------------------------- + +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. + +----------------------------------------------------------------- + +Notes: I programmed this on FreeBSD but should also compile without +big problems on Linux or other UNIX-like systems. +If you have tested one of those then pleace write me the name of the OS, +kernel version, make version and compiler & version. I will list it +right here: + +The following platforms have been tested with success: + +- FreeBSD 5.0-RELEASE, GCC 3.2.1, FreeBSD 5.0 make and GNU make 3.80 + +- Linux Kernel 2.4.19, GCC 3.2.0, GNU make 3.79.1 + +Before you compile the source you have to be sure to use at least GCC +version 3.x with pthreads enabled. ( Type gcc -v to check it ). +GCC 2.95 did not work while testing on linux and won't be supported! + +If you like to support yChat++, please write me an email and tell me +what you can/like/would help ;-]. Please also take a look at the +yChat++ homepage ( www.yChat.org ). + +Installation: Just invoke "make", edit the conf.txt and run the +server with ./ychat, point your webbrowser to http://yourip:port/index.html +( ignoring the index.html on the end of the url will not work! ). +... have fun :-). + +If you like customizing the design/layout/language of yChat, you will have +to edit msgs.h and glob.h before you compile the sources. Afterwards you can +change the html-template files which are placed in the html/ subdirectory. + +Files: + +conf.txt - The yChat configuration file. ( read by conf.cpp ). + +base.cpp - Encapsulates vector fields of room's or user ( may be later + hash_maps ) and provides methods for manipulating base data + objects. + +main.cpp - This includes the required manager headers for starting + the server and finally regulates the correct starting. + +reqp.cpp - This class implements the http request parser. If a client + starts a request to the server the reqp class will be + invoked. + +room.cpp - Specifies a chat room. For each chat room an instance of + this class exists. + +thrd.cpp - This class is needed by sock.cpp while creating a POSIX thread. + All data which a thread needs to do its tasks are stored in a + thrd object and then a pointer to it will be passed to the + POSIX thread function. + +user.cpp - Specifies a chat user. For each chat user an instance of + this class exists. + +Abstract classes: + +cont.cpp - All classes which need to store "key - value" data sets + inherit from this class. ( cont for content ). + +name.cpp - All classes which own a private member string name inherit + from this class. It also provides public get_name and + set_name methods. + +As described ( main.cpp ), there are so called managers. Managers are +accessible through their assigned wrapper classes and may be +instanciated only once. + +chat.cpp - The chat manager. Is responsible for managing the internal + data structure of the system and also covers a lot of + important methods of the system. + +conf.cpp - The config manager. Parses the config file specified in + glob.h and stores all the values of it in a map. + +html.cpp - The html-template manager. Reads the requested html-template + files, stores them in an internal cache ( averts reading + template-files from hd twice or more ) and parses the + partivular template in order to substituate dynamic values + of it. + +mutx.cpp - The mutex manager. Contains all global mutex handlers for + synchronizing POSIX thread shared data. until now only the + stdout is synchronized by mutx.cpp because most of objects + use their own mutex'. + +sock.cpp - The socket manager. Manages the socket connections. There + are multiplexed sockets. For each requests a new POSIX thread + will be created. + +Files written in capital letters contain static C++ classes + +CHAT.cpp - Static wrapper for the dynamic chat class. holds one global + reachable instance of chat until the program shuts down. + +CONF.cpp - Static wrapper for the dynamic conf class. holds one global + reachable instance of conf until the program shuts down. + +HTML.cpp - Static wrapper for the dynamic html class. holds one global + reachable instance of conf until the program shuts down. + +MUTX.cpp - Static wrapper for the dynamic mutx class. holds one global + reachable instance of conf until the program shuts down. + +SOCK.cpp - Static wrapper for the dynamic sock class. holds one global + reachable instance of conf until the program shuts down. + +TOOL.cpp - Static class which includes some usefull global reachable + methods which are not integraded in independent classes. + +Special header files ( all other header files which are not listed here +belong to their respective .cpp files ): + +data.h - Implements a generic class ( template class ) for accessing + data from a base ( see base.cpp ) object. this methods are + all inline and use rekursive algorithm and function pointers. + +glob.h - Defines global variables which are known by compilation + time. + +incl.h - This file is included from every other header file and + includes a set of headers which every class should be able + to use. + +msgs.h - Defines console output messages for verbosity level 0 ( see + glob.h for setting up verbosity levels ). and also defines + all the system messages. you may edit this file for translating + the system user language. + + +The basic class structure: + + base + | + | + data<type> name + / \ / \ + / \ / \ +chat room user + + cont + / \ + / \ +conf html + +History of lines of code ( including embedded comments ): + +Version: Lines: + Basic 0.1b 2402 diff --git a/SOCK.cpp b/SOCK.cpp new file mode 100644 index 0000000..c5b451e --- /dev/null +++ b/SOCK.cpp @@ -0,0 +1,10 @@ +#ifndef GSOC_CXX +#define GSOC_CXX + +#include "SOCK.h" + +using namespace std; + +sock* SOCK::obj; + +#endif @@ -0,0 +1,26 @@ +#ifndef GSOC_H +#define GSOC_H + +#include "sock.h" + +using namespace std; + +class SOCK +{ +private: + static sock* obj; + +public: + static void init() + { + obj = new sock(); + } + + static sock& get() + { + return *obj; + } +}; + + +#endif diff --git a/TOOL.cpp b/TOOL.cpp new file mode 100644 index 0000000..7709695 --- /dev/null +++ b/TOOL.cpp @@ -0,0 +1,33 @@ +#ifndef TOOL_CXX +#define TOOL_CXX + +#include <time.h> +#include "TOOL.h" + +int +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 +TOOL::unixtime() +{ + return (long) time( NULL ); +} + +#endif @@ -0,0 +1,15 @@ +#ifndef TOOL_H +#define TOOL_H + +#include "incl.h" + +using namespace std; + +class TOOL +{ +public: + static int string2int( string s_digit ); + static long unixtime(); +}; + +#endif @@ -1,65 +1,125 @@ -/* - This file is part of yChat - - $Author: paul $ - $Date: 2003/03/30 01:35:21 $ - - $Header: /home/cvsroot/ychat/base.cpp,v 1.7 2003/03/30 01:35:21 paul Exp $ -*/ // template class data implementation; #ifndef BASE_CPP #define BASE_CPP #include "base.h" +#include "MUTX.h" -template<class type> -base<type>::base() +base::base() { - map_elem = new hmap<name*,string>(80); - pthread_mutex_init (&mut_map_elem, NULL ); +#ifdef VERBOSE + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "base::base()" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + + pthread_mutex_init (&mut_vec_elem, NULL ); } -template<class type> -base<type>::~base( ) +base::~base( ) { - pthread_mutex_destroy( &mut_map_elem ); +#ifdef VERBOSE + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "base::~base( )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + + pthread_mutex_destroy( &mut_vec_elem ); } -template<class type> void -base<type>::add_elem( name* p_name ) +void +base::add_elem( name* p_name ) { - pthread_mutex_lock ( &mut_map_elem ); - map_elem->add_elem ( p_name, p_name->get_name()); - pthread_mutex_unlock( &mut_map_elem ); +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "base::add_elem( name* )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + + pthread_mutex_lock ( &mut_vec_elem ); + vec_elem.push_back ( p_name ); + pthread_mutex_unlock( &mut_vec_elem ); } -template<class type> void -base<type>::del_elem( string &s_name ) +bool +base::del_elem( string &s_name ) { - pthread_mutex_lock ( &mut_map_elem ); - map_elem->del_elem ( s_name ); - pthread_mutex_unlock( &mut_map_elem ); +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "base::del_elem( \"" << s_name << "\" )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + + vector<name*>::iterator iter; + pthread_mutex_lock ( &mut_vec_elem ); + + iter = vec_elem.begin(); + while( iter != vec_elem.end() ) + { + if ( (*iter)->get_name() == s_name ) + { + vec_elem.erase( iter ); + pthread_mutex_unlock( &mut_vec_elem ); + return true; + } + iter++; + } + + pthread_mutex_unlock( &mut_vec_elem ); + return false; } -template<class type> name* -base<type>::get_elem( string &s_name, bool &b_found ) +name* +base::get_elem( string &s_name, bool &b_found ) { - pthread_mutex_lock ( &mut_map_elem ); - name* p_name = map_elem->get_elem( s_name ); - pthread_mutex_unlock( &mut_map_elem ); +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "base:get_elem( \"" << s_name << "\", bool )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + + vector<name*>::iterator iter; + pthread_mutex_lock ( &mut_vec_elem ); + + iter = vec_elem.begin(); + while( iter != vec_elem.end() ) + { + if ( (*iter)->get_name() == s_name ) + { + b_found = true; + pthread_mutex_unlock( &mut_vec_elem ); + return (*iter); + } + iter++; + } - b_found = p_name == NULL ? false : true; + pthread_mutex_unlock( &mut_vec_elem ); - return p_name; + b_found = false; + + return new name(); } -template<class type> void -base<type>::run_func( void (*func)(name*, void*), void* v_arg ) +void +base::run_func( void (*func)(name*, void*), void* v_arg ) { - pthread_mutex_lock ( &mut_map_elem ); - map_elem->run_func( func, v_arg ); - pthread_mutex_unlock( &mut_map_elem ); +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "base:run_func( void (*func)(name*, void*), void* )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + + vector<name*>::iterator iter; + pthread_mutex_lock ( &mut_vec_elem ); + + // execute func foreach element of vec_elem with + // 1st argument: a pointer of a element of vec_elem. + // 2nd argument: a void pointer of a object. + for( iter = vec_elem.begin(); iter != vec_elem.end(); iter++ ) + ( *func ) ( (*iter), v_arg ); + + pthread_mutex_unlock( &mut_vec_elem ); } #endif @@ -3,76 +3,26 @@ #ifndef BASE_H #define BASE_H +#include <vector> #include "incl.h" -#include "hmap.h" #include "name.h" -template<class type> class base { private: - hmap<name*,string>* map_elem; - pthread_mutex_t mut_map_elem; + vector<name*> vec_elem ; + pthread_mutex_t mut_vec_elem; public: base(); ~base(); virtual void add_elem( name* p_name ); // add a element. - virtual void del_elem( string &s_name ); // delete a alement. + virtual bool del_elem( string &s_name ); // delete a alement. virtual name* get_elem( string &s_name, bool &b_found ); // get a element. - // execute func on all elements of map_elem. v_pointer is the argument. + // execute func on all elements of vec_elem. v_pointer is the argument. virtual void run_func( void (*func)(name*, 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_( name* name_obj, void* v_arg ) - { - string *p_msg = (string*) v_arg; - type *type_obj = static_cast<type*>(name_obj); - - 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_( name* name_obj, void* v_arg ) - { - map_string *map_params = (map_string*) v_arg; - type *type_obj = static_cast<type*>(name_obj); - - 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_( name* name_obj, void* v_arg ) - { - container *c = (container*) v_arg; - type *type_obj = static_cast<type*>(name_obj); - - type_obj -> get_user_list( *((string*)c->elem[0]), *((string*)c->elem[1]) ); - } }; -#include "base.cpp" - #endif @@ -1,26 +1,27 @@ // class chat implementation. -#ifndef s_chat_CXX -#define s_chat_CXX +#ifndef CHAT_CXX +#define CHAT_CXX #include "chat.h" -#include "s_conf.h" -#include "s_mutx.h" -#include "s_tool.h" +#include "CONF.h" +#include "MUTX.h" using namespace std; chat::chat( ) { - if ( s_conf::get().get_val( "HTML" ) == "OFF" ) - b_strip_html = true; - else - b_strip_html = false; +#ifdef VERBOSE + cout << "chat::chat()" << endl; +#endif } chat::~chat( ) { +#ifdef VERBOSE + cout << "chat::~chat()" << endl; +#endif } user* @@ -33,6 +34,12 @@ chat::get_user( string &s_user ) user* chat::get_user( string &s_user, bool &b_found ) { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "chat::get_user( " << s_user << ", bool& )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + container param; param.elem[0] = (void*) &s_user ; @@ -49,6 +56,11 @@ chat::get_user( string &s_user, bool &b_found ) void chat::get_user_( name *name_obj, void *v_arg ) { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "chat::get_user_( name *name_obj, void *v_arg )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif container* param = (container*) v_arg; room *room_obj = static_cast<room*>(name_obj); param->elem[2] = (void*)room_obj->get_elem( *((string*)param->elem[0]), *((bool*)param->elem[1]) ); @@ -57,21 +69,19 @@ chat::get_user_( name *name_obj, void *v_arg ) void chat::login( map_string &map_params ) { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "chat::login( map_params )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + string s_user = map_params["nick"]; - // prove if nick is empty: + // 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. + map_params["request"] = CONF::get().get_val( "STARTMPL" ); // redirect to the startpage. return; } @@ -82,7 +92,7 @@ chat::login( map_string &map_params ) if ( b_flag ) { map_params["INFO"] = E_ONLINE; - map_params["request"] = s_conf::get().get_val( "STARTMPL" ); + map_params["request"] = CONF::get().get_val( "STARTMPL" ); return; } @@ -94,10 +104,10 @@ chat::login( map_string &map_params ) { p_room = new room( s_room ); -#ifdef VERBOSE - pthread_mutex_lock ( &s_mutx::get().mut_stdout ); +#ifdef _VERBOSE + pthread_mutex_lock ( &MUTX::get().mut_stdout ); cout << NEWROOM << s_room << endl; - pthread_mutex_unlock( &s_mutx::get().mut_stdout ); + pthread_mutex_unlock( &MUTX::get().mut_stdout ); #endif add_elem( p_room ); @@ -111,36 +121,31 @@ chat::login( map_string &map_params ) // post "username enters the chat" into the room. p_room->msg_post( new string( s_user.append( USERENTR ) ) ); -#ifdef VERBOSE - pthread_mutex_lock ( &s_mutx::get().mut_stdout ); +#ifdef _VERBOSE + pthread_mutex_lock ( &MUTX::get().mut_stdout ); cout << LOGINPR << s_user << endl; - pthread_mutex_unlock( &s_mutx::get().mut_stdout ); + pthread_mutex_unlock( &MUTX::get().mut_stdout ); #endif } void -chat::post( user* p_user, map_string &map_params ) +chat::post( user* u_user, map_string &map_params ) { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "chat::post( user* u_user, map_string &map_params )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif - 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" ); + string s_msg( "<font color=\"" ); + s_msg.append( u_user->get_col1() ) + .append( "\">" ) + .append( u_user->get_name() ) + .append( ": " ) + .append( map_params["message"] ) + .append( "</font><br>\n" ); - p_user->get_p_room()->msg_post( &s_post ); + u_user->get_p_room()->msg_post( &s_msg ); } #endif @@ -1,20 +1,19 @@ // class chat declaration. -#ifndef s_chat_H -#define s_chat_H +#ifndef CHAT_H +#define CHAT_H #include <vector> #include "incl.h" -#include "base.h" +#include "data.h" #include "room.h" #include "user.h" using namespace std; -class chat : public base<room> +class chat : public data<room> { private: - bool b_strip_html; public: room* get_room( string &s_name, bool &b_found ) @@ -4,16 +4,26 @@ #define CMND_CXX #include "cmnd.h" -#include "s_mutx.h" +#include "MUTX.h" using namespace std; cmnd::cmnd( ) { +#ifdef VERBOSE + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "cmnd::cmnd( )" << cout; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif } cmnd::~cmnd() { +#ifdef VERBOSE + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "cmnd::~cmnd( )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif } #endif @@ -1,26 +1,36 @@ // class conf implementation. -#ifndef s_conf_CXX -#define s_conf_CXX +#ifndef CONF_CXX +#define CONF_CXX #include <fstream> #include "conf.h" using namespace std; -conf::conf( string s_conf = s_confILE ) : name( s_conf ) +conf::conf( string s_conf = CONFILE ) : name( s_conf ) { +#ifdef VERBOSE + cout << "conf::conf()" << endl; +#endif + parse( ); // parse the config file. } conf::~conf() { +#ifdef VERBOSE + cout << "conf::~conf()" << endl; +#endif } void conf::parse() { -#ifdef VERBOSE +#ifdef VERBOSE_ + cout << "conf::parse()" << endl; +#endif +#ifdef _VERBOSE cout << CFILEOK << get_name() << endl; #endif @@ -28,7 +38,7 @@ conf::parse() if ( ! fs_conf ) { -#ifdef VERBOSE +#ifdef _VERBOSE cout << CFILENO << get_name() << endl; #endif return; @@ -1,7 +1,7 @@ // class conf declaration. this class parses the server config file. -#ifndef s_conf_H -#define s_conf_H +#ifndef CONF_H +#define CONF_H #include "incl.h" #include "cont.h" @@ -11,53 +11,36 @@ # all lines which do not contain a semicolon and at least two quotes # or start with a # will be ignored. # -# greets, paul c. buetow ( snooper at ychat dot org ); +# greets, paul c. buetow ( snooper@ychat.org ); # # server specific configurations ( not allowed to be removed ): HTMLTEMP="html/"; # directory of the html-template files. -THRDPOOL="1"; # Initial pool size. -THRDPMAX="52"; # Max thread pool size -SRVRPORT="3000"; # local port on which the server listens. +THRDPOOL="100"; # thread pool size. every time all threads are used so many new + # threads will be added to the pool. +SRVRPORT="2000"; # local port on which the server listens. STRDROOM="Lounge"; # the name of the standard room. -LANGUAGE="en"; # language of the chat outputs ( CONSOLE OUTPUT IS NOT AFFECTED ) # the html template file which will be send if the requested file does not exists. NOTFOUND="notfound.html"; # specifies the standard start html-template. STARTMPL="index.html"; # user's standard nick color. -USERCOL1="#FFFFFF"; - -# length of the generated session id -SESSION_LENGTH="32"; - -# html = "OFF" strips all html tags from incoming messages -HTML="OFF"; - -# Logging - -# relative or absolute path to logfile -ACCESS_LOG="log/access_log"; - -# we're using buffered logging for performance -# LOG_LINES specifies after how many lines the log is flushed into a file -# if you don't want buffered logging set LOG_LINES to 1 -LOG_LINES="10"; +USERCOL1="#000000"; + +# superuser level names. level 0 has the most provileges. +SULEVEL0="Coder"; # programmer. +SULEVEL1="Admin"; # administrator. +SULEVEL2="Magic"; # super user with special privileges. +SULEVEL3="Super"; # temporary super user. +SULEVEL4="Basic"; # normal user without special privileges. +SULEVEL5="Guest"; # guest user, has almost no privileges. +SULEVEL6="Restr"; # a very restricted user. +SULEVEL7="Outbn"; # banned out of the system. # values which are used by the html-templates and are not sticked within the yC++ core source! GRAPHICS="http://paul.buetow.info/yChat"; # url for graphic files etc. -PGETITLE="yChat 0.5.2-LEGACY - Fast Simple Extensible"; - -# do not edit beyond this line - -CT_HTM="text/html"; -CT_HTML="text/html"; -CT_GIF="image/gif"; -CT_JPG="image/jpeg"; -CT_JPEG="image/jpeg"; -CT_PNG="image/png"; -CT_DEFAULT="text/html"; +PGETITLE="yChat++ Basic - Fast Simple Extensible"; # end. @@ -4,13 +4,18 @@ #define CONT_CXX #include "cont.h" -#include "s_mutx.h" +#include "MUTX.h" using namespace std; string cont::get_val( string s_key ) { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "cont::get_val( \"" << s_key << "\" )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif if ( map_vals.find( s_key ) != map_vals.end() ) return map_vals[ s_key ]; return string(); @@ -18,6 +23,12 @@ cont::get_val( string s_key ) cont::~cont() { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "cont::cont()" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + map_vals.~map_string(); } @@ -4,7 +4,6 @@ #define CONT_H #include "incl.h" -#include "hmap.h" using namespace std; @@ -0,0 +1,62 @@ +#ifndef DATA_H +#define DATA_H + +#include "base.h" +#include "MUTX.h" + +using namespace std; + +template<class type> +class data : public base +{ +public: + + // 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( &data<type>::msg_post_ , (void*)s_msg ); + } + static void msg_post_( name* name_obj, void* v_arg ) + { + string *p_msg = (string*) v_arg; + type *type_obj = static_cast<type*>(name_obj); + + type_obj -> msg_post( p_msg ); + } + + void get_data( map_string *p_map_string ) + { + run_func( &data<type>::get_data_ , (void*)p_map_string ); + } + static void get_data_( name* name_obj, void* v_arg ) + { + map_string *map_params = (map_string*) v_arg; + type *type_obj = static_cast<type*>(name_obj); + + 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( &data<type>::get_user_list_, (void*)&c ); + } + static void get_user_list_( name* name_obj, void* v_arg ) + { + container *c = (container*) v_arg; + type *type_obj = static_cast<type*>(name_obj); + + type_obj -> get_user_list( *((string*)c->elem[0]), *((string*)c->elem[1]) ); + } +}; + +#endif diff --git a/gfx/y_ani_black.gif b/gfx/y_ani_black.gif Binary files differindex 06274c2..06274c2 100755..100644 --- a/gfx/y_ani_black.gif +++ b/gfx/y_ani_black.gif diff --git a/gfx/y_ani_white.gif b/gfx/y_ani_white.gif Binary files differindex 168c937..168c937 100755..100644 --- a/gfx/y_ani_white.gif +++ b/gfx/y_ani_white.gif @@ -11,7 +11,7 @@ #define false 0 // config filename. -#define s_confILE "conf.txt" +#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. @@ -21,10 +21,20 @@ // max length of a line read from a socket or a file ( config-file, html-template ). #define READBUF 1024 +// if defined for every http request a new thread will be created. otherwise only for the +// chat streams extra threads will be created. THRDMOD2 DOES NOT WORK RIGHT NOW!! SO +// LET THIS DEFINE UNTOUCHED! BUGFIX WILL FOLLOW! +#define THRDMOD + // 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 +#define _VERBOSE + +// definition for verbosity level 1 ( constructors and destructors which are not inline ). +//#define VERBOSE +// definition for verbosity level 2 ( all methods which are not inline except VERBOSE 1 ). +//#define VERBOSE_ ////////////////////////////////////////////////////////////////////////////////////////// // DO NOT CHANGE ANYTHING BEHIND THIS LINE! @@ -1,23 +1,36 @@ // class html implementation. -#ifndef s_html_CXX -#define s_html_CXX +#ifndef HTML_CXX +#define HTML_CXX #include <fstream> #include "html.h" -#include "s_chat.h" -#include "s_mutx.h" +#include "CHAT.h" +#include "MUTX.h" using namespace std; html::html( ) { - set_name( s_conf::get().get_val( "HTMLTEMP" ) ); +#ifdef VERBOSE + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "html::html()" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + + set_name( CONF::get().get_val( "HTMLTEMP" ) ); + pthread_mutex_init( &mut_map_vals, NULL ); } html::~html( ) { +#ifdef VERBOSE + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "html::~html()" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + pthread_mutex_destroy( &mut_map_vals ); } @@ -32,6 +45,13 @@ html::clear_cache( ) string html::parse( map_string &map_params ) { + +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "html::parse( map_string& )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + string s_file = map_params["request"]; // check if s_file is in the container. @@ -43,34 +63,25 @@ html::parse( map_string &map_params ) if ( s_templ.empty() ) { auto string s_path = get_name(); - auto ifstream fs_templ( s_path.append( s_file ).c_str(), ios::binary ); + auto ifstream fs_templ( s_path.append( s_file ).c_str() ); 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" ); + map_params["request"] = CONF::get().get_val( "NOTFOUND" ); return parse( map_params ); - } - auto char c_buf; + auto char c_buf[READBUF]; + + while( fs_templ.getline( c_buf, READBUF ) ) + s_templ.append( string( c_buf ).append( "\n" ) ); - 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 ); +#ifdef _VERBOSE + pthread_mutex_lock ( &MUTX::get().mut_stdout ); cout << TECACHE << s_path << endl; - pthread_mutex_unlock( &s_mutx::get().mut_stdout ); + pthread_mutex_unlock( &MUTX::get().mut_stdout ); #endif // cache file. @@ -98,7 +109,7 @@ html::parse( map_string &map_params ) // 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 ); + auto string s_val = CONF::get().get_val( s_key ); // if s_val is empty use map_params. if ( s_val.empty() ) @@ -121,6 +132,12 @@ html::parse( map_string &map_params ) void html::online_list( user *p_user, map_string &map_params ) { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "html::online_list( user*, map_string& )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + // prepare user_list. string s_list ( "" ); string s_seperator( "<br>" ); @@ -1,15 +1,14 @@ // class html declaration. this class manages the html-template files. -#ifndef s_html_H -#define s_html_H +#ifndef HTML_H +#define HTML_H #include "incl.h" #include "cont.h" -#include "s_conf.h" +#include "CONF.h" #include "user.h" #include "name.h" - using namespace std; class html : public cont, name diff --git a/html/blank.html b/html/blank.html index 4ddd1a7..4ddd1a7 100755..100644 --- a/html/blank.html +++ b/html/blank.html diff --git a/html/frameset.html b/html/frameset.html index fe6b973..fe6b973 100755..100644 --- a/html/frameset.html +++ b/html/frameset.html diff --git a/html/index.html b/html/index.html index 66dca39..140272a 100755..100644 --- a/html/index.html +++ b/html/index.html @@ -1,27 +1,31 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> -<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <title> - %%yhttpd.version%% + %%PGETITLE%% </title> -<link rel=stylesheet href="style.css" type=text/css> </head> -<body> -<table align=center width=500> -<tr> -<td align=center class=header>%%yhttpd.version%%<br><br>%%INFO%%</td> -</tr> -<tr> -<td colspan=2> </td> -</tr> -<tr> -<td align=center colspan=2> -This is the demo website provided by yhttpd :-) -</td> -</tr> -</table> -<br><br> -<center><span class="signature">yhttpd is OpenSource - get it at <a class="fancy" target="_blank" href="http://www.yChat.org">http://www.yChat.org</a></span></center> +<body> +Welcome to +<pre> + ___ _ _ + _ _ / __\ |__ __ _| |_ +| | | |/ / | '_ \ / _` | __| +| |_| / /___| | | | (_| | |_ + \__, \____/|_| |_|\__,_|\__| + |___/ +</pre> + +<br> +%%PGETITLE%% +<br> +<br> +%%INFO%% +Enter your nick: +<form action="frameset.html"> + <input type="hidden" name="event" value="login"> + <input type="hidden" name="room" value="%%STRDROOM%%"> + <input type="text" name="nick"> + <input type="submit" value="login"> +</form> </body> </html> diff --git a/html/input.html b/html/input.html index a403d8e..e6fb016 100755..100644 --- a/html/input.html +++ b/html/input.html @@ -3,8 +3,6 @@ <title> %%PGETITLE%% </title> -<link rel=stylesheet href="style.css" type=text/css> - <script language="JavaScript"> <!-- function delout() @@ -21,7 +19,7 @@ //--> </script> </head> - <body bgcolor=#000000 text=#ffffff> + <body> <form name="input" action="input.html" target="blank" onsubmit="return delout();"> <input type="hidden" name="event" value="post"> <input type="hidden" name="nick" value="%%nick%%"> diff --git a/html/notfound.html b/html/notfound.html index a14d44b..574e341 100755..100644 --- a/html/notfound.html +++ b/html/notfound.html @@ -1,9 +1,7 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> -<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <title> - %%HTML_TITLE_TAG_CONTENT%% + %%PGETITLE%% </title> </head> <body> diff --git a/html/online.html b/html/online.html index aa14f8d..7f29b0e 100755..100644 --- a/html/online.html +++ b/html/online.html @@ -1,7 +1,6 @@ <html> <meta http-equiv="refresh" content="20"> -<link rel=stylesheet href="style.css" type=text/css> - <body bgcolor=#000000 text=#ffffff> + <body> %%MESSAGE%% </body> </html> diff --git a/html/stream.html b/html/stream.html index 6678069..66f8bbd 100755..100644 --- a/html/stream.html +++ b/html/stream.html @@ -3,7 +3,6 @@ <title> %%PGETITLE%% </title> -<link rel=stylesheet href="style.css" type=text/css> <script language="JavaScript"> function autoScroll() { @@ -24,7 +23,7 @@ } </script> </head> -<body bgcolor=#000000 text=#ffffff> +<body> Welcome to yChat %%nick%%! <br> <br> diff --git a/html/y_ani.gif b/html/y_ani.gif Binary files differindex e730988..e730988 100755..100644 --- a/html/y_ani.gif +++ b/html/y_ani.gif @@ -12,5 +12,6 @@ // include all the custom global variables. #include "glob.h" + // include all the custom messages. #include "msgs.h" @@ -1,6 +1,6 @@ /* - * yChat++; Contact: www.yChat.org; Mail@yChat.org - * Copyright (C) 2003 Paul C. Buetow, Volker Richter + * yChat++; Homepage: www.yChat.org + * Copyright (C) 2003 Paul C. Buetow ( Snooper@yChat.org, ICQ: 11655527 ) * ----------------------------------------------------------------- * * This program is free software; you can redistribute it and/or @@ -19,6 +19,7 @@ * */ + // needed for ignoring SIGPIPE. #include <signal.h> @@ -26,25 +27,25 @@ #include "incl.h" // include the chat manager. -#include "s_chat.h" +#include "CHAT.h" // include the config manager. -#include "s_conf.h" +#include "CONF.h" // include the html-template manager. -#include "s_html.h" +#include "HTML.h" // include the mutex manager for global synchronization. -#include "s_mutx.h" +#include "MUTX.h" // include the socket manager. -#include "s_sock.h" +#include "SOCK.h" using namespace std; int main() { -#ifdef VERBOSE +#ifdef _VERBOSE cout << " ___ _ _ " << endl << " _ _ / __\\ |__ __ _| |_ " << endl @@ -53,8 +54,9 @@ cout << " ___ _ _ " << endl << " \\__, \\____/|_| |_|\\__,_|\\__|" << endl << " |___/ " << endl << endl - << DESCRIP << endl - << VERSION << ", " + << DESCRIP + << VERSION << endl + << VERSION << endl << CONTACT << endl << SEPERAT << endl << STARTMS << endl ; @@ -66,19 +68,19 @@ cout << " ___ _ _ " << endl // 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_sock::init(); // init the socket manager. - s_chat::init(); // init the chat manager. + // the order of the initializations is very importand. for example the HTML::init() + // invokations assumes an initialized CONF class. + MUTX::init(); // init the mutex manager. + CONF::init(); // init the config manager. + HTML::init(); // init the html-template manager. + SOCK::init(); // init the socket manager. + 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(); + SOCK::get().start(); -#ifdef VERBOSE +#ifdef _VERBOSE cout << DOWNMSG << endl; #endif @@ -2,18 +2,13 @@ #define MSGS_H // message templates. - -// will be posed if a command does not exist for an user. -#define ERRORCMD " <font color='#FF0000'>No such command!</font><br>\n" // will post "nickname enters the chat" into the room. #define USERENTR " enters the chat<br>\n" -// will post "nickname leaves the chat" into the room. #define USERLEAV " leaves the chat<br>\n" // 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_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 @@ -24,8 +19,8 @@ #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 CONTACT "EMail: Snooper@yChat.org, ICQ: 11655527 " +#define DESCRIP "yChat++ Basic Copyright (C) 2003 Paul C. Buetow " #define DOWNMSG "Shutting down " #define LOGINPR "Login procedure succeeded for nick " #define NEWROOM "Adding room " @@ -36,8 +31,9 @@ #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: CVS" +#define THREAD1 "Spawning thread ( Mode 1 ) " +#define THREAD2 "Spawning thread ( Mode 2 ) " +#define THRPOOL "Refilling thread pool " +#define VERSION "Version Basic 0.1b (030320) " #endif @@ -1,7 +1,7 @@ // class mutx implementation. -#ifndef s_mutx_CXX -#define s_mutx_CXX +#ifndef MUTX_CXX +#define MUTX_CXX #include "mutx.h" @@ -9,11 +9,19 @@ using namespace std; mutx::mutx() { +#ifdef VERBOSE + cout << "mutx::mutx()" << endl; +#endif + pthread_mutex_init( &mut_stdout, NULL ); } mutx::~mutx() { +#ifdef VERBOSE + cout << "mutx::~mutx()" << endl; +#endif + pthread_mutex_destroy( &mut_stdout ); } @@ -1,7 +1,7 @@ // class mutx declaration. -#ifndef s_mutx_H -#define s_mutx_H +#ifndef MUTX_H +#define MUTX_H #include "incl.h" @@ -4,29 +4,51 @@ #define NAME_CXX #include "name.h" +#include "MUTX.h" using namespace std; name::name( string s_name ) { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "name::name( \"" << s_name << "\" )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + set_name( s_name ); } name::~name() { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "name::~name[ " << s_name << " ]" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif } string name::get_name() const { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "name::get_name()" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + return s_name; } void name::set_name( string s_name ) { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "name::set_name( \"" << s_name << "\" )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + this->s_name = s_name; } - - #endif @@ -14,15 +14,15 @@ protected: string s_name; // object's name. public: + // small inline methods: 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( ); + ~name(); }; #endif @@ -4,46 +4,43 @@ #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" +#include "CHAT.h" +#include "HTML.h" +#include "MUTX.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 = "Cache-control: no-cache\n"; +string reqp::HTTP_CACHEC = "Cash-control: no-cache\n"; string reqp::HTTP_CONNEC = "Connection: keep-alive\n"; -string reqp::HTTP_COTYPE = "Content-Type: "; +string reqp::HTTP_COTYPE = "Content-Type: text/html\n\n"; reqp::reqp( ) { +#ifdef VERBOSE + cout << "reqp::reqp()" << endl; +#endif } string -reqp::get_url( thrd* p_thrd, string s_req, map_string &map_params ) +reqp::get_url( 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 ); +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "reqp::get_url( s_req )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif - if( i_request == RQ_GET ) - s_ret.append( s_req.substr( 5, pos-6 ) ); - else - s_ret.append( s_req.substr( 6, pos-7 ) ); + auto unsigned int pos = s_req.find( "HTTP", 0 ); + string s_ret = s_req.substr( 5, pos-6 ); // remove ".." from the request. do { - pos = s_ret.find( "../", 0 ); + pos = s_ret.find( "..", 0 ); if ( pos == string::npos ) break; @@ -53,57 +50,37 @@ reqp::get_url( thrd* p_thrd, string s_req, map_string &map_params ) 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( "" ); + pos = s_ret.find( "?", 0 ); 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 ); - + auto string s_params = s_ret.substr( pos+1, s_ret.length() -pos-1 ); s_ret = s_ret.substr( 0, pos ); - } - if ( i_request == RQ_POST && s_params.empty() ) - { - char c_req[READBUF]; - read ( p_thrd->get_sock() , c_req, READBUF ); - s_params = string( strstr( c_req, "event" ) ); - } + auto unsigned int pos2; + do + { + pos = s_params.find( "=", 0 ); + if ( pos == string::npos ) + break; - auto unsigned int pos2; - do - { - pos = s_params.find( "=", 0 ); - if ( pos == string::npos ) - break; + pos2 = s_params.find( "&", 0 ); + if ( pos2 == string::npos ) + { + map_params[ s_params.substr( 0, pos ) ] = s_params.substr( pos+1, s_params.length()-pos-1 ); + 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; + map_params[ s_params.substr( 0, pos ) ] = s_params.substr( pos+1, pos2-pos-1 ); + s_params = s_params.substr( pos2+1, s_params.length()-pos2-1 ); } + while( true ); - 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 ); +#ifdef _VERBOSE + pthread_mutex_lock ( &MUTX::get().mut_stdout ); cout << REQUEST << s_ret << endl; - pthread_mutex_unlock( &s_mutx::get().mut_stdout ); + pthread_mutex_unlock( &MUTX::get().mut_stdout ); #endif map_params["request"] = s_ret; @@ -112,67 +89,14 @@ reqp::get_url( thrd* p_thrd, string s_req, map_string &map_params ) } string -reqp::getContentType( 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 ); -} - -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 ) { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "reqp::get_from_header( s_req, \"" << s_hdr << "\" )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + auto unsigned int pos[2]; pos[0] = s_req.find( s_hdr, 0 ); pos[1] = s_req.find( "\n", pos[0] ); @@ -182,19 +106,22 @@ reqp::get_from_header( string s_req, string s_hdr ) } string -reqp::parse( thrd* p_thrd, string s_req, map_string &map_params ) +reqp::parse( string s_req, map_string &map_params ) { - - // store all request informations in map_params. store the url in - // map_params["request"]. - get_url( p_thrd, s_req, map_params ); +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "reqp::parse( s_req )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif // 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( getContentType( map_params["request"] ) ); s_rep.append("\n\n"); + // store all request informations in map_params. store the url in + // map_params["request"]. + get_url( s_req, map_params ); // check the event variable. string s_event( map_params["event"] ); @@ -203,41 +130,33 @@ reqp::parse( thrd* p_thrd, string s_req, map_string &map_params ) // login procedure. if ( s_event == "login" ) { - s_chat::get().login( map_params ); + CHAT::get().login( map_params ); } else { bool b_found; - user* p_user = s_chat::get().get_user( map_params["nick"], b_found ); + user* u_user = CHAT::get().get_user( map_params["nick"], b_found ); if ( ! b_found ) { map_params["INFO"] = E_NOTONL; - map_params["request"] = s_conf::get().get_val( "STARTMPL" ); // redirect to the startpage. + map_params["request"] = 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 ); - } + CHAT::get().post( u_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 ); + HTML::get().online_list( u_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 ) ); + s_rep.append( HTML::get().parse( map_params ) ); // return the parsed html-template. return s_rep; @@ -3,12 +3,8 @@ #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; @@ -28,19 +24,15 @@ private: // 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 ); + virtual string get_url( 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 getContentType( string ); + virtual string parse( string s_req, map_string &map_params ); }; #endif @@ -4,15 +4,26 @@ #define ROOM_CXX #include "room.h" +#include "MUTX.h" using namespace std; room::room( string s_name ) : name( s_name ) { +#ifdef VERBOSE + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "room::room( \"" << s_name << "\" )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif } room::~room() { +#ifdef VERBOSE + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "room::~room[ " << get_name() << " ]" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif } #endif @@ -4,13 +4,13 @@ #define ROOM_H #include "incl.h" -#include "base.h" +#include "data.h" #include "name.h" #include "user.h" using namespace std; -class room : public base<user>, public name +class room : public data<user>, public name { private: @@ -1,35 +1,56 @@ // 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 +#ifndef SOCK_CXX +#define 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 "CHAT.h" +#include "CONF.h" +#include "MUTX.h" +#include "TOOL.h" #include "chat.h" #include "user.h" using namespace std; -sock::sock() + +// the posix thread function. this one will called every time a new request socket +// was created succsessfull. in this function a new POSIX thread life begins. +// be carefull because of synchronization issues!!!! +void *sock::posix_thread_func( void *v_pointer ) { - this->b_run = true; - this->i_req = 0; - this->req_parser = new reqp(); - this->thrd_pool = new pool(); +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "*posix_thread_func( void *v_pointer )" << endl; + pthread_mutex_unlock( &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 (); + + t->~thrd(); } -void -sock::chat_stream( int i_sock, user* p_user, map_string &map_params ) +void *sock::posix_thread_func_( void *v_pointer ) { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "*posix_thread_func_( void *v_pointer )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + + user *p_user = (user*) v_pointer; + string s_msg( "" ); + int i_sock = p_user->get_sock(); pthread_mutex_lock ( &(p_user->mut_message) ); while( p_user->get_online() ) @@ -39,7 +60,6 @@ sock::chat_stream( int i_sock, user* p_user, map_string &map_params ) if ( 0 > send( i_sock, s_msg.c_str(), s_msg.size(), 0 ) ) p_user->set_online( false ); } - pthread_mutex_unlock( &(p_user->mut_message) ); // remove the user from its room. @@ -52,9 +72,63 @@ sock::chat_stream( int i_sock, user* p_user, map_string &map_params ) p_user->~user(); } +sock::sock() +{ +#ifdef VERBOSE + cout << "sock::sock()" << endl; +#endif + + this->b_run = true; + this->i_req = 0; + this->req_parser = new reqp(); +} + +void +#ifdef THRDMOD +sock::chat_stream( int i_sock, map_string &map_params ) +#else +sock::chat_stream( int i_sock, map_string &map_params, queue<pthread_t> &thrd_pool ) +#endif +{ +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "sock::chat_stream( " << i_sock << ", map_string& )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + + user* p_user = CHAT::get().get_user( map_params["nick"] ); + p_user->set_sock( i_sock ); + +#ifdef THRDMOD + posix_thread_func_( (void*) p_user ); +#else + +#ifdef _VERBOSE + cout << THREAD2 << endl; +#endif + posix_thread_func_( (void*) p_user ); + + auto int i_fail = pthread_create( &thrd_pool.front(), NULL, posix_thread_func_, (void*) p_user ); + + // remove this thread from thread pool because its now in use. + thrd_pool.pop(); + + // check if the thread started correctly. + if ( i_fail ) + { + cerr << "Thrd: error with return code " << i_fail << endl; + } + +#endif +} + int sock::make_socket( uint16_t i_port ) { +#ifdef VERBOSE_ + cout << "sock::make_socket( " << i_port << " )" << endl; +#endif + int sock; struct sockaddr_in name; @@ -75,9 +149,6 @@ sock::make_socket( uint16_t i_port ) 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) { @@ -94,13 +165,18 @@ sock::make_socket( uint16_t i_port ) } int -sock::read_write( thrd* p_thrd, int i_sock ) +sock::read_write( int i_sock ) { - char c_req[2048]; +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "sock::read_write( " << i_sock << " )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + char c_req[2048]; int i_bytes; i_bytes = read (i_sock, c_req, 2048); - + if (i_bytes < 0) { cerr << "Sock: read error " << endl; @@ -111,17 +187,20 @@ sock::read_write( thrd* p_thrd, int i_sock ) // stores the request params. map_string map_params; - // get the s_rep ( s_html response which will be send imediatly to the client + // get the s_rep ( HTML response which will be send imediatly to the client // and fill map_params with request values. - auto string s_temp=(string)c_req; - - string s_rep = req_parser->parse( p_thrd, string( c_req ), map_params ); + string s_rep = req_parser->parse( string( c_req ), map_params ); // send s_rep to the client. send( i_sock, s_rep.c_str(), s_rep.size(), 0 ); - // dont need those vals anymore. - map_params.clear(); + // prove if this is a request for a chat stream! + if ( map_params["event"] == "stream" ) +#ifdef THRDMOD + chat_stream( i_sock, map_params ); +#else + chat_stream( i_sock, map_params, thrd_pool ); +#endif return 0; } @@ -129,10 +208,36 @@ sock::read_write( thrd* p_thrd, int i_sock ) return -1; } +void +sock::refill_thrd_pool( ) +{ +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "sock::refill_thrd_pool( )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif +#ifdef _VERBOSE + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << THRPOOL << i_thrd_pool_size << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + + for (int i=0; i<i_thrd_pool_size; i++ ) + { + pthread_t new_thread; + thrd_pool.push( new_thread ); + } +} + int sock::start() { - auto int i_port = s_tool::string2int( s_conf::get().get_val( "SRVRPORT" ) ); +#ifdef VERBOSE_ + cout << "sock::start( )" << endl; +#endif + + i_thrd_pool_size = TOOL::string2int( CONF::get().get_val( "THRDPOOL" ) ); + auto int i_port = TOOL::string2int( CONF::get().get_val( "SRVRPORT" ) ); int sock; fd_set active_fd_set, read_fd_set; @@ -140,7 +245,7 @@ sock::start() struct sockaddr_in clientname; size_t size; -#ifdef VERBOSE +#ifdef _VERBOSE cout << SOCKCRT << "localhost:" << i_port << endl; #endif @@ -153,7 +258,7 @@ sock::start() exit( EXIT_FAILURE ); } -#ifdef VERBOSE +#ifdef _VERBOSE cout << SOCKRDY << endl; #endif @@ -191,7 +296,7 @@ sock::start() close ( new_sock ); } -#ifdef VERBOSE +#ifdef _VERBOSE cout << CONNECT << i_req << " " << inet_ntoa( clientname.sin_addr ) << ":" @@ -204,7 +309,36 @@ sock::start() else { - thrd_pool->run( (void*) new thrd( i ) ); + // create a client thread object. this one will contain all data which is needed by a new posix + // thread in order to do its tasks. the thr_client pointer will be passed to the posix function + // there the life of a new thread begins. + thrd* thr_client = new thrd( i ); + + // if the thread pool is empty refill it. + if ( thrd_pool.empty() ) + refill_thrd_pool( ); + +#ifndef THRDMOD + posix_thread_func( (void*) thr_client ); + +#else +#ifdef _VERBOSE + cout << THREAD1 << endl; +#endif + + // creating a new posix thread. + auto int i_fail = pthread_create( &thrd_pool.front(), NULL, posix_thread_func, (void*) thr_client ); + + // remove this thread from thread pool because its now in use. + thrd_pool.pop(); + // check if the thread started correctly. + if ( i_fail ) + { + cerr << "Thrd: error with return code " << i_fail << endl; + close ( i ); + } + +#endif FD_CLR( i, &active_fd_set ); } } @@ -1,7 +1,7 @@ // class sock declaration. -#ifndef s_sock_H -#define s_sock_H +#ifndef SOCK_H +#define SOCK_H #include <queue> #include <arpa/inet.h> @@ -15,10 +15,8 @@ #include <unistd.h> #include "incl.h" -#include "pool.h" #include "reqp.h" #include "thrd.h" -#include "user.h" using namespace std; @@ -27,14 +25,24 @@ class sock private: // total number of server requests. unsigned long long int i_req; + queue<pthread_t> thrd_pool; + + int i_thrd_pool_size; bool b_run; // true while socket manager is running. reqp* req_parser; // parses the http requests from clients. - pool* thrd_pool; // the thread pool. - // creates a server socket. + // the chat stream there all the chat messages will sent through. +#ifdef THRDMOD + static void chat_stream( int i_sock, map_string &map_params ); +#else + static void chat_stream( int i_sock, map_string &map_params, queue<pthread_t> &thrd_pool ); +#endif virtual int make_socket( uint16_t port ); + static void *posix_thread_func ( void *v_pointer ); + static void *posix_thread_func_( void *v_pointer ); + public: // small inline methods: bool get_run() const { return b_run; } @@ -42,12 +50,10 @@ public: // public methods. explicit sock( ); // simple constructor. - virtual int read_write( thrd* p_thrd, int filedes ); + virtual int read_write( 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 ); - + virtual void refill_thrd_pool( ); // refills the thread pool with new thewads. }; #endif @@ -4,25 +4,43 @@ #define THRD_CXX #include "thrd.h" -#include "s_sock.h" +#include "MUTX.h" +#include "SOCK.h" using namespace std; thrd::thrd( int i_sock ) { +#ifdef VERBOSE + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "thrd::thrd( " << i_sock << " )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + this->i_sock = i_sock; } thrd::~thrd() { +#ifdef VERBOSE + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "thrd::~thrd()" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + shutdown ( get_sock() , 2 ); - close ( get_sock() ); } void thrd::run() { - s_sock::get().read_write( this, i_sock ); +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "thrd::run()" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + + SOCK::get().read_write( i_sock ); } #endif @@ -1,11 +1,7 @@ -BRAIN-STORMING: - mysql -security: tempid and crypto +tempid commands -hash_map []-operator -hash_map in cont -several different html templatetes - -10: bugfixes -20: goto 10 +hash_maps +free pthread memory ( reusable thread pool ? ) +pthread mode 2 +semaphore sync ( ?? ) @@ -4,30 +4,41 @@ #define USER_CXX #include "user.h" -#include "s_conf.h" -#include "s_tool.h" +#include "CONF.h" +#include "MUTX.h" +#include "TOOL.h" using namespace std; user::user( string s_name ) : name( s_name ) { +#ifdef VERBOSE + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "user::user( string \"" << s_name << "\" )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + this -> b_online = true; - this -> l_time = s_tool::unixtime(); - this -> s_col1 = s_conf::get().get_val( "USERCOL1" ); + this -> l_time = TOOL::unixtime(); + this -> s_col1 = 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_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); + pthread_mutex_init( &mut_message, NULL); } user::~user() { +#ifdef VERBOSE + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "user::~user[ \"" << get_name() << "\" ]" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + 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 ); @@ -38,6 +49,12 @@ user::~user() void user::get_data( map_string *p_map_data ) { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "user::get_data( map_string* )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + string s_req = (*p_map_data)["!get"]; // get the nick and the color of the user. @@ -48,6 +65,12 @@ user::get_data( map_string *p_map_data ) string user::get_mess( ) { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "user::get_mess( )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + string s_ret( "" ); pthread_mutex_lock ( &mut_s_mess ); s_ret.append( s_mess ); @@ -60,6 +83,12 @@ user::get_mess( ) bool user::get_online( ) { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "user::get_online( )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + bool b_ret; pthread_mutex_lock ( &mut_b_online ); b_ret = b_online; @@ -70,6 +99,12 @@ user::get_online( ) void user::set_online( bool b_online ) { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "user::set_online( bool )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + pthread_mutex_lock ( &mut_b_online ); this -> b_online = b_online; pthread_mutex_unlock( &mut_b_online ); @@ -78,6 +113,12 @@ user::set_online( bool b_online ) room* user::get_p_room( ) { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "user::get_p_room( )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + room* p_return; pthread_mutex_lock ( &mut_p_room ); p_return = p_room; @@ -88,46 +129,39 @@ user::get_p_room( ) void user::set_p_room( room* p_room ) { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "user::set_p_room( void* )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + 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 ) -{ - msg_post( new string( ERRORCMD ) ); -} - void user::renew_stamp( ) { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "user::renew_stamp( )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif pthread_mutex_lock ( &mut_l_time ); - l_time = s_tool::unixtime(); + l_time = TOOL::unixtime(); pthread_mutex_unlock( &mut_l_time ); } void user::msg_post( string *p_msg ) { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "user::msg_post_( string* )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + pthread_mutex_lock ( &mut_s_mess ); s_mess.append( *p_msg ); pthread_mutex_unlock( &mut_s_mess ); @@ -138,6 +172,12 @@ user::msg_post( string *p_msg ) void user::get_user_list( string &s_list, string &s_seperator ) { +#ifdef VERBOSE_ + pthread_mutex_lock ( &MUTX::get().mut_stdout ); + cout << "user::get_user_list( string &s_list, string &s_seperator )" << endl; + pthread_mutex_unlock( &MUTX::get().mut_stdout ); +#endif + s_list.append( "<font color=\"" ) .append( get_col1() ) .append( "\">" ) @@ -3,7 +3,6 @@ #define USER_H #include "incl.h" -#include "hmap.h" #include "name.h" using namespace std; @@ -27,7 +26,6 @@ private: 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; @@ -40,6 +38,9 @@ public: string get_col1() const { return s_col1; } void set_col1 ( string s_col1 ) { this -> s_col1 = s_col1; } + int get_sock() const { return i_sock; } + void set_sock ( int i_sock ) { this -> i_sock = i_sock; } + rang get_rang ( ) const { return r_rang; } void set_rang ( rang r_rang ) { r_oldr = this -> r_rang; this -> r_rang = r_rang; } @@ -59,18 +60,12 @@ public: 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 ); + virtual void renew_stamp(); // 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. |
