summaryrefslogtreecommitdiff
path: root/ychat-0.4
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2013-04-06 13:14:41 +0200
committerPaul Buetow <paul@buetow.org>2013-04-06 13:14:41 +0200
commit9cd3ccffd5372dfde3af478e3f832f18db4be3f1 (patch)
tree631c295a4a4a16b57502b847626763a279bf6df7 /ychat-0.4
parent13aaf70af703748fe096e0664c305cd202637ad2 (diff)
tagging tags
Diffstat (limited to 'ychat-0.4')
-rw-r--r--ychat-0.4/COPYING339
-rw-r--r--ychat-0.4/CVS/Entries70
-rw-r--r--ychat-0.4/CVS/Entries.Log4
-rw-r--r--ychat-0.4/CVS/Repository1
-rw-r--r--ychat-0.4/CVS/Root1
-rwxr-xr-xychat-0.4/Makefile.in12
-rwxr-xr-xychat-0.4/README179
-rwxr-xr-xychat-0.4/base.cpp65
-rwxr-xr-xychat-0.4/base.h71
-rwxr-xr-xychat-0.4/chat.cpp147
-rwxr-xr-xychat-0.4/chat.h46
-rwxr-xr-xychat-0.4/cmnd.cpp19
-rwxr-xr-xychat-0.4/cmnd.h18
-rw-r--r--ychat-0.4/cmnd/CVS/Entries3
-rw-r--r--ychat-0.4/cmnd/CVS/Repository1
-rw-r--r--ychat-0.4/cmnd/CVS/Root1
-rw-r--r--ychat-0.4/cmnd/yc_q.cpp21
-rw-r--r--ychat-0.4/cmnd/yc_test.cpp12
-rwxr-xr-xychat-0.4/conf.cpp75
-rwxr-xr-xychat-0.4/conf.h24
-rwxr-xr-xychat-0.4/conf.txt72
-rwxr-xr-xychat-0.4/configure1555
-rw-r--r--ychat-0.4/configure.in28
-rwxr-xr-xychat-0.4/cont.cpp24
-rwxr-xr-xychat-0.4/cont.h26
-rw-r--r--ychat-0.4/gfx/CVS/Entries3
-rw-r--r--ychat-0.4/gfx/CVS/Repository1
-rw-r--r--ychat-0.4/gfx/CVS/Root1
-rwxr-xr-xychat-0.4/gfx/y_ani_black.gifbin0 -> 61100 bytes
-rwxr-xr-xychat-0.4/gfx/y_ani_white.gifbin0 -> 53536 bytes
-rwxr-xr-xychat-0.4/glob.h63
-rw-r--r--ychat-0.4/hmap.cpp180
-rw-r--r--ychat-0.4/hmap.h118
-rwxr-xr-xychat-0.4/html.cpp140
-rwxr-xr-xychat-0.4/html.h42
-rw-r--r--ychat-0.4/html/CVS/Entries11
-rw-r--r--ychat-0.4/html/CVS/Repository1
-rw-r--r--ychat-0.4/html/CVS/Root1
-rwxr-xr-xychat-0.4/html/blank.html4
-rwxr-xr-xychat-0.4/html/frameset.html20
-rwxr-xr-xychat-0.4/html/index.html32
-rwxr-xr-xychat-0.4/html/input.html34
-rwxr-xr-xychat-0.4/html/notfound.html10
-rwxr-xr-xychat-0.4/html/online.html7
-rwxr-xr-xychat-0.4/html/stream.html30
-rw-r--r--ychat-0.4/html/style.css11
-rwxr-xr-xychat-0.4/html/y_ani.gifbin0 -> 35107 bytes
-rwxr-xr-xychat-0.4/html/y_black.gifbin0 -> 61100 bytes
-rwxr-xr-xychat-0.4/incl.h16
-rwxr-xr-xychat-0.4/lang.cpp78
-rwxr-xr-xychat-0.4/lang.h24
-rw-r--r--ychat-0.4/lang/CVS/Entries3
-rw-r--r--ychat-0.4/lang/CVS/Repository1
-rw-r--r--ychat-0.4/lang/CVS/Root1
-rw-r--r--ychat-0.4/lang/de3
-rw-r--r--ychat-0.4/lang/en3
-rw-r--r--ychat-0.4/logd.cpp65
-rw-r--r--ychat-0.4/logd.h24
-rwxr-xr-xychat-0.4/main.cpp98
-rwxr-xr-xychat-0.4/modl.cpp98
-rwxr-xr-xychat-0.4/modl.h29
-rwxr-xr-xychat-0.4/msgs.h36
-rwxr-xr-xychat-0.4/mutx.cpp20
-rwxr-xr-xychat-0.4/mutx.h21
-rwxr-xr-xychat-0.4/name.cpp32
-rwxr-xr-xychat-0.4/name.h28
-rwxr-xr-xychat-0.4/pool.cpp214
-rwxr-xr-xychat-0.4/pool.h77
-rwxr-xr-xychat-0.4/reqp.cpp281
-rwxr-xr-xychat-0.4/reqp.h47
-rwxr-xr-xychat-0.4/room.cpp18
-rwxr-xr-xychat-0.4/room.h34
-rw-r--r--ychat-0.4/s_chat.cpp10
-rw-r--r--ychat-0.4/s_chat.h26
-rw-r--r--ychat-0.4/s_conf.cpp10
-rw-r--r--ychat-0.4/s_conf.h26
-rw-r--r--ychat-0.4/s_html.cpp10
-rw-r--r--ychat-0.4/s_html.h26
-rw-r--r--ychat-0.4/s_lang.cpp10
-rw-r--r--ychat-0.4/s_lang.h26
-rw-r--r--ychat-0.4/s_modl.cpp10
-rw-r--r--ychat-0.4/s_modl.h26
-rw-r--r--ychat-0.4/s_mutx.cpp10
-rw-r--r--ychat-0.4/s_mutx.h26
-rw-r--r--ychat-0.4/s_sman.cpp10
-rw-r--r--ychat-0.4/s_sman.h26
-rw-r--r--ychat-0.4/s_sock.cpp10
-rw-r--r--ychat-0.4/s_sock.h26
-rw-r--r--ychat-0.4/s_tool.cpp111
-rw-r--r--ychat-0.4/s_tool.h19
-rw-r--r--ychat-0.4/sess.cpp35
-rw-r--r--ychat-0.4/sess.h28
-rw-r--r--ychat-0.4/sman.cpp48
-rw-r--r--ychat-0.4/sman.h32
-rwxr-xr-xychat-0.4/sock.cpp235
-rwxr-xr-xychat-0.4/sock.h53
-rwxr-xr-xychat-0.4/thrd.cpp28
-rwxr-xr-xychat-0.4/thrd.h26
-rwxr-xr-xychat-0.4/todo.txt11
-rwxr-xr-xychat-0.4/user.cpp170
-rwxr-xr-xychat-0.4/user.h84
101 files changed, 5942 insertions, 0 deletions
diff --git a/ychat-0.4/COPYING b/ychat-0.4/COPYING
new file mode 100644
index 0000000..a43ea21
--- /dev/null
+++ b/ychat-0.4/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/ychat-0.4/CVS/Entries b/ychat-0.4/CVS/Entries
new file mode 100644
index 0000000..ba61f67
--- /dev/null
+++ b/ychat-0.4/CVS/Entries
@@ -0,0 +1,70 @@
+/COPYING/1.1/Fri Mar 28 00:27:16 2003//
+/Makefile.in/1.7/Sat Apr 19 16:16:14 2003//
+/README/1.2/Wed Apr 2 10:50:18 2003//
+/base.cpp/1.8/Wed Apr 2 10:50:18 2003//
+/base.h/1.5/Wed Apr 2 10:50:18 2003//
+/chat.cpp/1.12/Sat Apr 19 19:39:17 2003//
+/chat.h/1.8/Sat Apr 19 16:16:14 2003//
+/cmnd.cpp/1.3/Tue Mar 25 14:54:07 2003//
+/cmnd.h/1.1.1.1/Fri Mar 21 15:54:56 2003//
+/conf.cpp/1.5/Fri Apr 4 21:35:59 2003//
+/conf.h/1.2/Tue Mar 25 14:54:07 2003//
+/conf.txt/1.18/Sat Apr 19 16:16:14 2003//
+/configure/1.4/Fri Mar 28 02:02:00 2003//
+/configure.in/1.5/Fri Mar 28 02:02:00 2003//
+/cont.cpp/1.3/Tue Mar 25 14:54:07 2003//
+/cont.h/1.2/Sun Mar 30 00:26:42 2003//
+/glob.h/1.5/Fri Apr 4 21:35:59 2003//
+/hmap.cpp/1.8/Mon Apr 7 13:24:09 2003//
+/hmap.h/1.8/Wed Apr 2 10:50:18 2003//
+/html.cpp/1.7/Wed Apr 2 10:50:18 2003//
+/html.h/1.3/Tue Mar 25 14:54:07 2003//
+/incl.h/1.1.1.1/Fri Mar 21 15:54:56 2003//
+/lang.cpp/1.1/Fri Apr 4 22:14:35 2003//
+/lang.h/1.1/Fri Apr 4 22:14:35 2003//
+/logd.cpp/1.2/Thu Apr 10 15:36:10 2003//
+/logd.h/1.1/Fri Apr 4 15:19:11 2003//
+/main.cpp/1.11/Sat Apr 19 16:16:14 2003//
+/modl.cpp/1.2/Wed Apr 2 21:57:34 2003//
+/modl.h/1.1/Wed Apr 2 13:23:09 2003//
+/msgs.h/1.10/Mon Apr 7 13:18:23 2003//
+/mutx.cpp/1.3/Tue Mar 25 14:54:07 2003//
+/mutx.h/1.2/Tue Mar 25 14:54:08 2003//
+/name.cpp/1.3/Tue Mar 25 22:19:51 2003//
+/name.h/1.3/Tue Mar 25 22:21:26 2003//
+/pool.cpp/1.6/Tue Mar 25 14:54:08 2003//
+/pool.h/1.1/Sun Mar 23 04:55:58 2003//
+/reqp.cpp/1.15/Sat Apr 19 19:39:17 2003//
+/reqp.h/1.10/Fri Apr 4 15:19:11 2003//
+/room.cpp/1.2/Sun Mar 23 05:41:19 2003//
+/room.h/1.2/Fri Mar 28 02:51:03 2003//
+/s_chat.cpp/1.1/Tue Mar 25 14:54:08 2003//
+/s_chat.h/1.1/Tue Mar 25 14:54:08 2003//
+/s_conf.cpp/1.1/Tue Mar 25 14:54:08 2003//
+/s_conf.h/1.2/Fri Apr 4 21:35:59 2003//
+/s_html.cpp/1.1/Tue Mar 25 14:54:08 2003//
+/s_html.h/1.1/Tue Mar 25 14:54:08 2003//
+/s_lang.cpp/1.1/Fri Apr 4 22:14:35 2003//
+/s_lang.h/1.1/Fri Apr 4 22:14:35 2003//
+/s_modl.cpp/1.1/Wed Apr 2 23:01:20 2003//
+/s_modl.h/1.1/Wed Apr 2 23:01:20 2003//
+/s_mutx.cpp/1.1/Tue Mar 25 14:54:08 2003//
+/s_mutx.h/1.1/Tue Mar 25 14:54:08 2003//
+/s_sman.cpp/1.1/Sat Apr 19 16:16:15 2003//
+/s_sman.h/1.1/Sat Apr 19 16:17:09 2003//
+/s_sock.cpp/1.1/Tue Mar 25 14:54:08 2003//
+/s_sock.h/1.1/Tue Mar 25 14:54:08 2003//
+/s_tool.cpp/1.4/Fri Apr 4 10:41:12 2003//
+/s_tool.h/1.4/Fri Apr 4 10:41:12 2003//
+/sess.cpp/1.2/Sat Apr 19 19:39:17 2003//
+/sess.h/1.2/Sat Apr 19 19:39:17 2003//
+/sman.cpp/1.1/Sat Apr 19 16:16:15 2003//
+/sman.h/1.2/Sat Apr 19 19:39:17 2003//
+/sock.cpp/1.16/Sat Apr 19 19:39:17 2003//
+/sock.h/1.6/Fri Apr 4 15:19:11 2003//
+/thrd.cpp/1.5/Wed Mar 26 14:57:04 2003//
+/thrd.h/1.1.1.1/Fri Mar 21 15:54:56 2003//
+/todo.txt/1.4/Sun Mar 30 01:48:46 2003//
+/user.cpp/1.7/Fri Apr 4 22:14:35 2003//
+/user.h/1.8/Sat Apr 19 19:39:17 2003//
+D
diff --git a/ychat-0.4/CVS/Entries.Log b/ychat-0.4/CVS/Entries.Log
new file mode 100644
index 0000000..89d073a
--- /dev/null
+++ b/ychat-0.4/CVS/Entries.Log
@@ -0,0 +1,4 @@
+A D/cmnd////
+A D/gfx////
+A D/html////
+A D/lang////
diff --git a/ychat-0.4/CVS/Repository b/ychat-0.4/CVS/Repository
new file mode 100644
index 0000000..7c108c7
--- /dev/null
+++ b/ychat-0.4/CVS/Repository
@@ -0,0 +1 @@
+ychat
diff --git a/ychat-0.4/CVS/Root b/ychat-0.4/CVS/Root
new file mode 100644
index 0000000..2818c02
--- /dev/null
+++ b/ychat-0.4/CVS/Root
@@ -0,0 +1 @@
+:pserver:rover@cvs.ychat.berlios.de:/cvsroot/ychat
diff --git a/ychat-0.4/Makefile.in b/ychat-0.4/Makefile.in
new file mode 100755
index 0000000..300d035
--- /dev/null
+++ b/ychat-0.4/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/ychat-0.4/README b/ychat-0.4/README
new file mode 100755
index 0000000..fd72da4
--- /dev/null
+++ b/ychat-0.4/README
@@ -0,0 +1,179 @@
+yChat++; Homepage: www.yChat.org; Version CVS
+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.
+
+-----------------------------------------------------------------
+
+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 "./configure" and afterwards "make", edit the
+conf.txt and run the server with ./ychat. Then 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 data
+ objects.
+
+hmap.cpp - The hash map implementation which is a very fast data
+ structure. is needed for saving users, rooms and so on.
+
+main.cpp - This includes the required manager headers for starting
+ the server and finally regulates the correct starting.
+
+modl.cpp - The module loader. Stores pointers of all dynamic loaded
+ yChat modules in a hash map object and loads new modules
+ if desired or returns their pointers.
+
+pool.cpp - The implementation of the thread pool. all threads are stored
+ in a queue. Each thread will be reused if the assigned job is
+ finished.
+
+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
+
+s_chat.cpp - Static wrapper for the dynamic chat class. holds one global
+ reachable instance of chat until the program shuts down.
+
+s_conf.cpp - Static wrapper for the dynamic conf class. holds one global
+ reachable instance of conf until the program shuts down.
+
+s_html.cpp - Static wrapper for the dynamic html class. holds one global
+ reachable instance of conf until the program shuts down.
+
+s_mutx.cpp - Static wrapper for the dynamic mutx class. holds one global
+ reachable instance of conf until the program shuts down.
+
+s_sock.cpp - Static wrapper for the dynamic sock class. holds one global
+ reachable instance of conf until the program shuts down.
+
+s_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 ):
+
+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<room> base<user>
+ | | name
+ | | / \
+ | | / \
+ chat room user
+
+ cont
+ / \
+ / \
+conf html
+
+Version Lines of code
+ 0.1 2402
+ 0.2 2377
+
+New in 0.2:
+ - POST request now work.
+ - Thread pool ( pool.cpp ).
+ - Bugfixes
diff --git a/ychat-0.4/base.cpp b/ychat-0.4/base.cpp
new file mode 100755
index 0000000..ce585ea
--- /dev/null
+++ b/ychat-0.4/base.cpp
@@ -0,0 +1,65 @@
+/*
+ This file is part of yChat
+
+ $Author: snooper $
+ $Date: 2003/04/02 10:50:18 $
+
+ $Header: /cvsroot/ychat/ychat/base.cpp,v 1.8 2003/04/02 10:50:18 snooper Exp $
+*/
+// template class data implementation;
+
+#ifndef BASE_CPP
+#define BASE_CPP
+
+#include "base.h"
+
+template<class type>
+base<type>::base()
+{
+ map_elem = new hmap<type*,string>(80);
+ pthread_mutex_init (&mut_map_elem, NULL );
+}
+
+template<class type>
+base<type>::~base( )
+{
+ pthread_mutex_destroy( &mut_map_elem );
+}
+
+template<class type> void
+base<type>::add_elem( type* p_type )
+{
+ pthread_mutex_lock ( &mut_map_elem );
+ map_elem->add_elem ( p_type, p_type->get_name());
+ pthread_mutex_unlock( &mut_map_elem );
+}
+
+template<class type> void
+base<type>::del_elem( string &s_name )
+{
+ pthread_mutex_lock ( &mut_map_elem );
+ map_elem->del_elem ( s_name );
+ pthread_mutex_unlock( &mut_map_elem );
+}
+
+template<class type> type*
+base<type>::get_elem( string &s_name, bool &b_found )
+{
+ pthread_mutex_lock ( &mut_map_elem );
+ type* p_type = map_elem->get_elem( s_name );
+ pthread_mutex_unlock( &mut_map_elem );
+
+ b_found = p_type == NULL ? false : true;
+
+ return p_type;
+}
+
+template<class type> void
+base<type>::run_func( void (*func)(type*, void*), void* v_arg )
+{
+ pthread_mutex_lock ( &mut_map_elem );
+ map_elem->run_func( func, v_arg );
+ pthread_mutex_unlock( &mut_map_elem );
+}
+
+#endif
diff --git a/ychat-0.4/base.h b/ychat-0.4/base.h
new file mode 100755
index 0000000..6f06e4b
--- /dev/null
+++ b/ychat-0.4/base.h
@@ -0,0 +1,71 @@
+// template class data declaration;
+
+#ifndef BASE_H
+#define BASE_H
+
+#include "incl.h"
+#include "hmap.h"
+
+template<class type>
+class base
+{
+private:
+ hmap<type*,string>* map_elem;
+ pthread_mutex_t mut_map_elem;
+
+public:
+ base();
+ ~base();
+
+ virtual void add_elem( type* p_type ); // add a element.
+ virtual void del_elem( string &s_name ); // delete a alement.
+ virtual type* get_elem( string &s_name, bool &b_found ); // get a element.
+
+ // execute func on all elements of map_elem. v_pointer is the argument.
+ virtual void run_func( void (*func)(type*, void*), void* v_arg );
+
+ // chat::msg_post sends to all users of the system a message.
+ // room::msg_post sends to all users of the room a message.
+ // user::msg_post sends to the user a message.
+ void msg_post( string *s_msg )
+ {
+ run_func( &base<type>::msg_post_ , (void*)s_msg );
+ }
+ static void msg_post_( type* type_obj, void* v_arg )
+ {
+ string *p_msg = (string*) v_arg;
+ type_obj -> msg_post( p_msg );
+ }
+
+ void get_data( map_string *p_map_string )
+ {
+ run_func( &base<type>::get_data_ , (void*)p_map_string );
+ }
+ static void get_data_( type* type_obj, void* v_arg )
+ {
+ map_string *map_params = (map_string*) v_arg;
+ type_obj -> get_data ( map_params );
+ }
+
+ // chat::get_user_list gets a list of all users of the system.
+ // room::get_user_list gets a list of all users of the room.
+ // user::get_user_list gets a "list" of a user <font color="usercolor">username</font>seperator
+ void get_user_list( string &s_list, string &s_seperator )
+ {
+
+ container c;
+ c.elem[0] = (void*) &s_list;
+ c.elem[1] = (void*) &s_seperator;
+
+ run_func( &base<type>::get_user_list_, (void*)&c );
+ }
+ static void get_user_list_( type* type_obj, void* v_arg )
+ {
+ container *c = (container*) v_arg;
+ type_obj -> get_user_list( *((string*)c->elem[0]), *((string*)c->elem[1]) );
+ }
+};
+
+#include "base.cpp"
+
+#endif
diff --git a/ychat-0.4/chat.cpp b/ychat-0.4/chat.cpp
new file mode 100755
index 0000000..b845ec3
--- /dev/null
+++ b/ychat-0.4/chat.cpp
@@ -0,0 +1,147 @@
+// class chat implementation.
+
+#ifndef s_chat_CXX
+#define s_chat_CXX
+
+#include "chat.h"
+#include "s_conf.h"
+#include "s_mutx.h"
+#include "s_tool.h"
+
+using namespace std;
+
+chat::chat( )
+{
+ if ( s_conf::get().get_val( "HTML" ) == "OFF" )
+ b_strip_html = true;
+ else
+ b_strip_html = false;
+
+}
+
+chat::~chat( )
+{
+}
+
+user*
+chat::get_user( string &s_user )
+{
+ bool b_flag;
+ return get_user( s_user, b_flag );
+}
+
+user*
+chat::get_user( string &s_user, bool &b_found )
+{
+ container param;
+
+ param.elem[0] = (void*) &s_user ;
+ param.elem[1] = (void*) &b_found;
+
+ b_found = false;
+
+ run_func( get_user_, (void*)&param );
+
+ if ( *( (bool*)param.elem[1] ) )
+ return (user*)param.elem[2];
+}
+
+void
+chat::get_user_( room *room_obj, void *v_arg )
+{
+ container* param = (container*) v_arg;
+ param->elem[2] = (void*)room_obj->get_elem( *((string*)param->elem[0]), *((bool*)param->elem[1]) );
+}
+
+void
+chat::login( map_string &map_params )
+{
+ string s_user = map_params["nick"];
+
+ // prove if nick is empty:
+ if ( s_user.empty() )
+ {
+ map_params["INFO"] = E_NONICK;
+ map_params["request"] = s_conf::get().get_val( "STARTMPL" ); // redirect to the startpage.
+ return;
+ }
+
+ // prove if the nick ist alphanumeric:
+ else if ( ! s_tool::is_alpha_numeric( s_user ) )
+ {
+ map_params["INFO"] = E_ALPNUM;
+ map_params["request"] = s_conf::get().get_val( "STARTMPL" ); // redirect to the startpage.
+ return;
+ }
+
+ bool b_flag;
+
+ // prove if nick is already online / logged in.
+ get_user( s_user, b_flag );
+ if ( b_flag )
+ {
+ map_params["INFO"] = E_ONLINE;
+ map_params["request"] = s_conf::get().get_val( "STARTMPL" );
+ return;
+ }
+
+ string s_room = map_params["room"];
+ room* p_room = get_room( s_room , b_flag );
+
+ // if room does not exist add room to list!
+ if ( ! b_flag )
+ {
+ p_room = new room( s_room );
+
+#ifdef VERBOSE
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cout << NEWROOM << s_room << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+#endif
+
+ add_elem( p_room );
+ }
+
+ user *p_user = new user( s_user );
+
+ // add user to the room.
+ p_room->add_user( p_user );
+ sess *ns =s_sman::get().createSession();
+ ns->setValue(string("nick"), (void *)new string(s_user) );
+ map_params["tmpid"]=ns->getId();
+ // post "username enters the chat" into the room.
+ p_room->msg_post( new string( s_user.append( s_lang::get().get_val( "USERENTR" ) ) ) );
+
+#ifdef VERBOSE
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cout << LOGINPR << s_user << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+#endif
+}
+
+void
+chat::post( user* p_user, map_string &map_params )
+{
+
+ string s_msg( map_params["message"] );
+
+ auto unsigned i_pos = s_msg.find( "/" );
+ if ( i_pos == 0 )
+ return p_user->command( s_msg );
+
+ if ( b_strip_html )
+ s_tool::strip_html( &s_msg );
+
+ string s_post( "<font color=\"" );
+
+ s_post.append( p_user->get_col1() )
+ .append( "\">" )
+ .append( p_user->get_name() )
+ .append( ": " )
+ .append( s_msg )
+ .append( "</font><br>\n" );
+
+ p_user->get_p_room()->msg_post( &s_post );
+}
+
+#endif
diff --git a/ychat-0.4/chat.h b/ychat-0.4/chat.h
new file mode 100755
index 0000000..60bcf9d
--- /dev/null
+++ b/ychat-0.4/chat.h
@@ -0,0 +1,46 @@
+// class chat declaration.
+
+#ifndef s_chat_H
+#define s_chat_H
+
+#include <vector>
+#include "incl.h"
+#include "base.h"
+#include "room.h"
+#include "user.h"
+#include "sess.h"
+#include "s_lang.h"
+#include "s_sman.h"
+
+using namespace std;
+
+class chat : public base<room>
+{
+private:
+ bool b_strip_html;
+
+public:
+
+
+ room* get_room( string &s_name, bool &b_found )
+ {
+ return static_cast<room*>( get_elem( s_name, b_found ) );
+ }
+
+ // public methods:
+ explicit chat(); // a standard constructor.
+ ~chat(); // destructor.
+
+ // get the object of a specific user.
+ virtual user* get_user( string &s_nick );
+ virtual user* get_user( string &s_nick, bool &b_found );
+ static void get_user_( room* room_obj, void *v_arg );
+
+ // will be called every time a user tries to login.
+ virtual void login( map_string &map_params );
+
+ // will be called if a user posts a message.
+ virtual void post ( user* u_user, map_string &map_params );
+};
+
+#endif
diff --git a/ychat-0.4/cmnd.cpp b/ychat-0.4/cmnd.cpp
new file mode 100755
index 0000000..28e73a7
--- /dev/null
+++ b/ychat-0.4/cmnd.cpp
@@ -0,0 +1,19 @@
+// class cmnd implementation.
+
+#ifndef CMND_CXX
+#define CMND_CXX
+
+#include "cmnd.h"
+#include "s_mutx.h"
+
+using namespace std;
+
+cmnd::cmnd( )
+{
+}
+
+cmnd::~cmnd()
+{
+}
+
+#endif
diff --git a/ychat-0.4/cmnd.h b/ychat-0.4/cmnd.h
new file mode 100755
index 0000000..2eb1db2
--- /dev/null
+++ b/ychat-0.4/cmnd.h
@@ -0,0 +1,18 @@
+// class cmnd declaration.
+
+#ifndef CMND_H
+#define CMND_H
+
+#include "incl.h"
+
+using namespace std;
+
+class cmnd
+{
+public:
+ // public methods:
+ explicit cmnd( ); // a standard constructor.
+ ~cmnd( );
+};
+
+#endif
diff --git a/ychat-0.4/cmnd/CVS/Entries b/ychat-0.4/cmnd/CVS/Entries
new file mode 100644
index 0000000..5f48d3a
--- /dev/null
+++ b/ychat-0.4/cmnd/CVS/Entries
@@ -0,0 +1,3 @@
+/yc_q.cpp/1.2/Wed Apr 2 21:57:34 2003//
+/yc_test.cpp/1.1/Wed Apr 2 10:52:16 2003//
+D
diff --git a/ychat-0.4/cmnd/CVS/Repository b/ychat-0.4/cmnd/CVS/Repository
new file mode 100644
index 0000000..d7cf3ae
--- /dev/null
+++ b/ychat-0.4/cmnd/CVS/Repository
@@ -0,0 +1 @@
+ychat/cmnd
diff --git a/ychat-0.4/cmnd/CVS/Root b/ychat-0.4/cmnd/CVS/Root
new file mode 100644
index 0000000..2818c02
--- /dev/null
+++ b/ychat-0.4/cmnd/CVS/Root
@@ -0,0 +1 @@
+:pserver:rover@cvs.ychat.berlios.de:/cvsroot/ychat
diff --git a/ychat-0.4/cmnd/yc_q.cpp b/ychat-0.4/cmnd/yc_q.cpp
new file mode 100644
index 0000000..acc8596
--- /dev/null
+++ b/ychat-0.4/cmnd/yc_q.cpp
@@ -0,0 +1,21 @@
+#include <iostream>
+#include "../user.h"
+
+/*
+ gcc -shared -o yc_name.so yc_name.cpp
+*/
+
+using namespace std;
+
+
+extern "C" {
+ export int extern_function(void *v_arg);
+
+ int extern_function(void *v_arg)
+ {
+ user *p_user = (user*) v_arg;
+ p_user->msg_post( new string( "<script language='JavaScript'> window.open( 'index.html', '_top' ); </script>\n " ) );
+ p_user->set_online( false );
+ }
+}
+
diff --git a/ychat-0.4/cmnd/yc_test.cpp b/ychat-0.4/cmnd/yc_test.cpp
new file mode 100644
index 0000000..deb3e54
--- /dev/null
+++ b/ychat-0.4/cmnd/yc_test.cpp
@@ -0,0 +1,12 @@
+#include <iostream>
+
+using namespace std;
+
+extern "C" {
+ export int function(void *v_arg);
+
+ int function(void *v_arg)
+ {
+ cout << "Hallo " << (char*)v_arg << endl;
+ }
+}
diff --git a/ychat-0.4/conf.cpp b/ychat-0.4/conf.cpp
new file mode 100755
index 0000000..3ff71b8
--- /dev/null
+++ b/ychat-0.4/conf.cpp
@@ -0,0 +1,75 @@
+// class conf implementation.
+
+#ifndef s_conf_CXX
+#define s_conf_CXX
+
+#include <fstream>
+#include "conf.h"
+
+using namespace std;
+
+conf::conf( string s_conf = CONFILE ) : name( s_conf )
+{
+ parse( ); // parse the config file.
+}
+
+conf::~conf()
+{
+}
+
+void
+conf::parse()
+{
+#ifdef VERBOSE
+ cout << CFILEOK << get_name() << endl;
+#endif
+
+ ifstream fs_conf( get_name().c_str() );
+
+ if ( ! fs_conf )
+ {
+#ifdef VERBOSE
+ cout << CFILENO << get_name() << endl;
+#endif
+ return;
+ }
+
+ char c_buf[READBUF];
+
+ while( fs_conf.getline( c_buf, READBUF ) )
+ {
+ string s_token( c_buf );
+ unsigned int ui_pos = s_token.find( "#", 0 );
+
+ // if line is commented out:
+ if ( ui_pos == 0 )
+ continue;
+
+ ui_pos = s_token.find( ";", 0 );
+
+ // if token has not been found.
+ if ( ui_pos == string::npos )
+ continue;
+
+ s_token = s_token.substr( 0 , --ui_pos );
+ ui_pos = s_token.find ( "\"", 0 );
+
+ if ( ui_pos == string::npos )
+ continue;
+
+ string s_val = s_token.substr( ui_pos+1, s_token.length() );
+ string s_key = s_token.substr( 0 , --ui_pos );
+
+#ifdef VERBOSE2
+ cout << s_key << "=" << s_val << endl;
+#endif
+
+ // fill the map.
+ map_vals[s_key] = s_val;
+ }
+
+ fs_conf.close();
+ fs_conf.~ifstream();
+}
+
+#endif
diff --git a/ychat-0.4/conf.h b/ychat-0.4/conf.h
new file mode 100755
index 0000000..6e2a890
--- /dev/null
+++ b/ychat-0.4/conf.h
@@ -0,0 +1,24 @@
+// class conf declaration. this class parses the server config file.
+
+#ifndef s_conf_H
+#define s_conf_H
+
+#include "incl.h"
+#include "cont.h"
+#include "name.h"
+
+using namespace std;
+
+class conf : public cont, name
+{
+private:
+
+public:
+ // public methods:
+ conf ( string s_conf ); // standard constructor.
+ ~conf(); // standard destructor.
+
+ virtual void parse( ); // parses the config file.
+};
+
+#endif
diff --git a/ychat-0.4/conf.txt b/ychat-0.4/conf.txt
new file mode 100755
index 0000000..78c8a1e
--- /dev/null
+++ b/ychat-0.4/conf.txt
@@ -0,0 +1,72 @@
+#
+# please notice this:
+# the server parses this configuration file while starting or by an
+# administrator's request.
+#
+# not allowed are semicolons ';' inside or before the quotes " ",
+# otherwise this might result in errors.
+#
+# the syntax is easy: KEYNAME="value";
+#
+# 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@ychat.org );
+#
+
+# server specific configurations ( not allowed to be removed ):
+
+HTMLTEMP="html/"; # directory of the html-template files.
+THRDPOOL="50"; # thread pool size.
+THRDQUEU="50"; # length of the thread pool queue.
+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";
+
+# 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.
+
+# length of the generated session id
+SESSION_LENGTH="64";
+
+# html = "OFF" strips all html tags from incoming messages
+HTML="OFF";
+
+# Logging
+
+# relative or absolute path to logfile
+ACCESS_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";
+
+# 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++ Basic - 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";
+
+# end.
diff --git a/ychat-0.4/configure b/ychat-0.4/configure
new file mode 100755
index 0000000..8c5f0a7
--- /dev/null
+++ b/ychat-0.4/configure
@@ -0,0 +1,1555 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=s_chat.h
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+#AC_INIT_AUTOMAKE(yChat, 0.2)
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:528: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 533 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:544: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_cygwin=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:561: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 566 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:573: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_mingw32=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:590: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 605 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:611: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 622 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:628: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 639 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:645: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:674: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CXX="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CXX="$ac_cv_prog_CXX"
+if test -n "$CXX"; then
+ echo "$ac_t""$CXX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CXX" && break
+done
+test -n "$CXX" || CXX="gcc"
+
+
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:706: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 717 "configure"
+#include "confdefs.h"
+
+int main(){return(0);}
+EOF
+if { (eval echo configure:722: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cxx_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cxx_cross=no
+ else
+ ac_cv_prog_cxx_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cxx_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
+if test $ac_cv_prog_cxx_works = no; then
+ { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:748: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
+cross_compiling=$ac_cv_prog_cxx_cross
+
+echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
+echo "configure:753: checking whether we are using GNU C++" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.C <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:762: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gxx=yes
+else
+ ac_cv_prog_gxx=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gxx" 1>&6
+
+if test $ac_cv_prog_gxx = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+
+ac_test_CXXFLAGS="${CXXFLAGS+set}"
+ac_save_CXXFLAGS="$CXXFLAGS"
+CXXFLAGS=
+echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
+echo "configure:781: checking whether ${CXX-g++} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.cc
+if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
+ ac_cv_prog_cxx_g=yes
+else
+ ac_cv_prog_cxx_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS="$ac_save_CXXFLAGS"
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+
+
+
+echo $ac_n "checking for library containing dlopen""... $ac_c" 1>&6
+echo "configure:815: checking for library containing dlopen" >&5
+if eval "test \"`echo '$''{'ac_cv_search_dlopen'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_func_search_save_LIBS="$LIBS"
+ac_cv_search_dlopen="no"
+cat > conftest.$ac_ext <<EOF
+#line 822 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo configure:833: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_dlopen="none required"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+test "$ac_cv_search_dlopen" = "no" && for i in dl; do
+LIBS="-l$i $ac_func_search_save_LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 844 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo configure:855: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_dlopen="-l$i"
+break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+LIBS="$ac_func_search_save_LIBS"
+fi
+
+echo "$ac_t""$ac_cv_search_dlopen" 1>&6
+if test "$ac_cv_search_dlopen" != "no"; then
+ test "$ac_cv_search_dlopen" = "none required" || LIBS="$ac_cv_search_dlopen $LIBS"
+
+else :
+
+fi
+if test "$ac_cv_search_dlopen" = "-ldl"; then
+LDFLAGS="$ac_cv_search_dlopen"
+fi
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
+echo "configure:883: checking for $ac_hdr that defines DIR" >&5
+if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 888 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <$ac_hdr>
+int main() {
+DIR *dirp = 0;
+; return 0; }
+EOF
+if { (eval echo configure:896: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ ac_header_dirent=$ac_hdr; break
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
+echo "configure:921: checking for opendir in -ldir" >&5
+ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldir $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 929 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:940: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -ldir"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
+echo "configure:962: checking for opendir in -lx" >&5
+ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lx $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 970 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:981: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -lx"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1004: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1009 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1017: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1034 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1052 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1073 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1084: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1111: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1116 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1121: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_hdr in string.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1151: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1156 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1161: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:1188: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1193 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:1242: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:1263: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat > conftest.$ac_ext <<EOF
+#line 1270 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:1277: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+ inline | yes) ;;
+ no) cat >> confdefs.h <<\EOF
+#define inline
+EOF
+ ;;
+ *) cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@CPP@%$CPP%g
+s%@CXX@%$CXX%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/ychat-0.4/configure.in b/ychat-0.4/configure.in
new file mode 100644
index 0000000..7512df7
--- /dev/null
+++ b/ychat-0.4/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/ychat-0.4/cont.cpp b/ychat-0.4/cont.cpp
new file mode 100755
index 0000000..a437543
--- /dev/null
+++ b/ychat-0.4/cont.cpp
@@ -0,0 +1,24 @@
+// class cont implementation.
+
+#ifndef CONT_CXX
+#define CONT_CXX
+
+#include "cont.h"
+#include "s_mutx.h"
+
+using namespace std;
+
+string
+cont::get_val( string s_key )
+{
+ if ( map_vals.find( s_key ) != map_vals.end() )
+ return map_vals[ s_key ];
+ return string();
+}
+
+cont::~cont()
+{
+ map_vals.~map_string();
+}
+
+#endif
diff --git a/ychat-0.4/cont.h b/ychat-0.4/cont.h
new file mode 100755
index 0000000..90cbd7b
--- /dev/null
+++ b/ychat-0.4/cont.h
@@ -0,0 +1,26 @@
+// class cont declaration. defines a simple data container class.
+
+#ifndef CONT_H
+#define CONT_H
+
+#include "incl.h"
+#include "hmap.h"
+
+using namespace std;
+
+class cont
+{
+protected:
+ map_string map_vals;
+
+public:
+ cont::~cont();
+
+ // small inline methods:
+ void clear_vals() { map_vals.clear(); } // removes all values.
+
+ // public methods:
+ virtual string get_val( string s_key ); // get a specific map_vals value.
+};
+
+#endif
diff --git a/ychat-0.4/gfx/CVS/Entries b/ychat-0.4/gfx/CVS/Entries
new file mode 100644
index 0000000..5178e8f
--- /dev/null
+++ b/ychat-0.4/gfx/CVS/Entries
@@ -0,0 +1,3 @@
+/y_ani_black.gif/1.1.1.1/Fri Mar 21 15:54:56 2003//
+/y_ani_white.gif/1.1.1.1/Fri Mar 21 15:54:56 2003//
+D
diff --git a/ychat-0.4/gfx/CVS/Repository b/ychat-0.4/gfx/CVS/Repository
new file mode 100644
index 0000000..6d97963
--- /dev/null
+++ b/ychat-0.4/gfx/CVS/Repository
@@ -0,0 +1 @@
+ychat/gfx
diff --git a/ychat-0.4/gfx/CVS/Root b/ychat-0.4/gfx/CVS/Root
new file mode 100644
index 0000000..2818c02
--- /dev/null
+++ b/ychat-0.4/gfx/CVS/Root
@@ -0,0 +1 @@
+:pserver:rover@cvs.ychat.berlios.de:/cvsroot/ychat
diff --git a/ychat-0.4/gfx/y_ani_black.gif b/ychat-0.4/gfx/y_ani_black.gif
new file mode 100755
index 0000000..06274c2
--- /dev/null
+++ b/ychat-0.4/gfx/y_ani_black.gif
Binary files differ
diff --git a/ychat-0.4/gfx/y_ani_white.gif b/ychat-0.4/gfx/y_ani_white.gif
new file mode 100755
index 0000000..168c937
--- /dev/null
+++ b/ychat-0.4/gfx/y_ani_white.gif
Binary files differ
diff --git a/ychat-0.4/glob.h b/ychat-0.4/glob.h
new file mode 100755
index 0000000..15fc7ba
--- /dev/null
+++ b/ychat-0.4/glob.h
@@ -0,0 +1,63 @@
+// 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
+
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// 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/ychat-0.4/hmap.cpp b/ychat-0.4/hmap.cpp
new file mode 100644
index 0000000..662a203
--- /dev/null
+++ b/ychat-0.4/hmap.cpp
@@ -0,0 +1,180 @@
+#ifndef hmap_cpp
+#define hmap_cpp
+
+
+#include "hmap.h"
+
+using namespace std;
+
+bool isPrime( int n );
+int nextPrime( int n );
+
+// Construct the hash table.
+template <class obj_type, class key_type>
+hmap<obj_type, key_type>::hmap( double mop )
+ : maxOccupiedPercentage(mop), array( nextPrime( 101 ) )
+{
+ cout << "hmap Constructor" << endl;
+ lookups = 0;
+ make_empty( );
+}
+
+// Insert item x into the hash table. If the item is
+// already present, do nothing
+template <class obj_type, class key_type>
+void hmap<obj_type, key_type>::add_elem( const obj_type &x, const key_type &k )
+{
+ // Insert x as active
+ int currentPos = findPos( k );
+ if( isActive( currentPos ) )
+ return;
+
+ array[ currentPos ] = hash_entry( x, k, ACTIVE );
+ // cout << "Inserted=" << x << "= at " << currentPos << endl;
+ if( ++occupied > array.size( ) * maxOccupiedPercentage )
+ rehash( );
+}
+
+// Expand the hash table.
+template <class obj_type, class key_type>
+void hmap<obj_type, key_type>::rehash( )
+{
+ vector<hash_entry> oldArray = array;
+
+ // Create new double-sized, empty table
+ array.resize( nextPrime( 2 * oldArray.size( ) ) );
+ for( int j = 0; j < array.size( ); j++ )
+ array[ j ].info = EMPTY;
+
+ // Copy table over
+ make_empty( );
+ for( int i = 0; i < oldArray.size( ); i++ )
+ if( oldArray[ i ].info == ACTIVE )
+ add_elem( oldArray[ i ].element, oldArray[ i ].key );
+}
+
+// Hash function, can only handle strings.
+// If you want to hash other objects you will have to
+// create a hash table for them
+template <class obj_type, class key_type>
+unsigned int hmap<obj_type, key_type>::hash( const string & key ) const
+{
+ unsigned int hashVal = 0;
+ // cout << key << "%";
+
+ for( size_t i = 0; i < key.size(); i++ )
+ hashVal = ( hashVal << 5 ) ^ key[ i ] ^ hashVal;
+
+ return hashVal;
+}
+
+// Method that performs quadratic probing resolution.
+// Return the position where the search for x terminates.
+template <class obj_type, class key_type>
+int hmap<obj_type, key_type>::findPos( const key_type &k )
+{
+ int collisionNum = 0;
+ int currentPos = hash( k ) % array.size( );
+ lookups++;
+
+ while( array[ currentPos ].info != EMPTY &&
+ array[ currentPos ].key != k )
+ {
+ // cout << array[ currentPos ].element << "!=" << x << endl;
+ lookups++;
+ currentPos += 2 * ++collisionNum - 1; // Compute ith probe
+
+ if( currentPos >= array.size( ) )
+ currentPos -= array.size( );
+ }
+
+ // cout << currentPos << " ";
+ return currentPos;
+}
+
+// Remove item x from the hash table.
+template <class obj_type, class key_type>
+void hmap<obj_type, key_type>::del_elem( const key_type & k )
+{
+ int currentPos = findPos( k );
+ if( isActive( currentPos ) )
+ array[ currentPos ].info = DELETED;
+}
+
+// Find item x in the hash table.
+// Return a pointer to the matching item or 0 if not found
+template <class obj_type, class key_type>
+obj_type hmap<obj_type, key_type>::get_elem( const key_type &k )
+{
+ int currentPos = findPos( k );
+ if( isActive( currentPos ) )
+ return array[ currentPos ].element;
+ else
+ return 0;
+}
+
+// Make the hash table logically empty.
+template <class obj_type, class key_type>
+void hmap<obj_type, key_type>::make_empty( )
+{
+ occupied = 0;
+ for( int i = 0; i < array.size( ); i++ )
+ array[ i ].info = EMPTY;
+}
+
+// Return true if currentPos exists and is active.
+template <class obj_type, class key_type>
+bool hmap<obj_type, key_type>::isActive( int currentPos ) const
+{
+ return array[ currentPos ].info == ACTIVE;
+}
+
+
+// Internal method to test if a positive number is prime.
+// Not an efficient algorithm.
+template <class obj_type, class key_type>
+bool hmap<obj_type, key_type>::isPrime( int n ) const
+{
+ if( n == 2 || n == 3 )
+ return true;
+
+ else if( n == 1 || n % 2 == 0 )
+ return false;
+
+ for( int i = 3; i * i <= n; i += 2 )
+ if( n % i == 0 )
+ return false;
+
+ return true;
+}
+
+// Internal method to return a prime number at least as large as n.
+// Assumes n > 0.
+template <class obj_type, class key_type>
+int hmap<obj_type, key_type>::nextPrime( int n ) const
+{
+ if( n % 2 == 0 )
+ n++;
+
+ for( ; !isPrime( n ); n += 2 );
+
+ return n;
+}
+template<class obj_type, class key_type> void
+hmap<obj_type, key_type>::run_func( void (*func)(obj_type) )
+{
+ for( int i = 0; i < array.size( ); i++ )
+ if ( array[i].info == ACTIVE )
+ ( *func ) ( array[i].element );
+}
+
+template<class obj_type, class key_type> void
+hmap<obj_type, key_type>::run_func( void (*func)(obj_type, void*), void* v_arg )
+{
+ for( int i = 0; i < array.size( ); i++ )
+ if ( array[i].info == ACTIVE )
+ ( *func ) ( array[i].element, v_arg );
+}
+
+#endif
+
diff --git a/ychat-0.4/hmap.h b/ychat-0.4/hmap.h
new file mode 100644
index 0000000..2392133
--- /dev/null
+++ b/ychat-0.4/hmap.h
@@ -0,0 +1,118 @@
+#pragma warning(disable:4786)
+
+#ifndef hmap_h
+#define hmap_h
+
+#include <vector>
+#include "incl.h"
+
+using namespace std;
+
+// void add_elem( obj_type x, key_type k ) --> Insert x
+// void del_elem( key_type k ) --> Remove x
+// obj_type get_elem( key_type k ) --> Return item that matches x
+// void make_empty( ) --> Remove all items
+
+template <class obj_type, class key_type>
+class hmap
+{
+private:
+ enum entry_type
+ {
+ ACTIVE, EMPTY, DELETED
+ };
+
+ struct hash_entry
+ {
+ obj_type element;
+ key_type key;
+ entry_type info;
+
+ hash_entry( const obj_type &e = obj_type( ), const key_type &k = key_type( ), entry_type i = EMPTY ) : element( e ), key( k ), info( i ) { }
+ };
+
+ int occupied;
+
+ virtual bool isActive( int currentPos ) const;
+ virtual void rehash( );
+ virtual bool isPrime ( int n ) const;
+ virtual int nextPrime( int n ) const;
+ double maxOccupiedPercentage;
+
+protected:
+ int lookups;
+ unsigned int hash( const string &key ) const;
+ vector<hash_entry> array;
+
+public:
+ hmap( double moc );
+
+ virtual int findPos ( const key_type &k );
+ virtual void make_empty( );
+ virtual void add_elem ( const obj_type &x, const key_type &k );
+ virtual void del_elem ( const key_type &k );
+ virtual obj_type get_elem ( const key_type &k );
+
+ virtual void run_func( void (*func)(obj_type) );
+ virtual void run_func( void (*func)(obj_type, void*), void* v_arg );
+
+ // inline:
+ void getSize()
+ {
+ int size = 0;
+ for( int j = 0; j < array.size( ); j++ )
+ if (array[ j ].info == ACTIVE)
+ size++;
+ return size;
+ };
+
+ int getLookups()
+ {
+ return lookups;
+ };
+
+ int getCapacity()
+ {
+ return array.size();
+ };
+
+ double getLambda()
+ {
+ return static_cast<double>(getSize())/static_cast<double>(getCapacity());
+ }
+
+ obj_type& operator[]( key_type &k )
+ {
+ return get_elem( k );
+ }
+
+};
+
+template <class obj_type, class key_type>
+class linearhmap : public hmap<obj_type, key_type> {
+public:
+ linearhmap(double moc) : hmap<obj_type, key_type>(moc) {};
+
+ virtual int findPos( const key_type &k )
+ {
+ int collisionNum = 0;
+ int currentPos = hash( k ) % array.size( );
+ lookups++;
+
+ while( array[ currentPos ].info != EMPTY &&
+ array[ currentPos ].key != k )
+ {
+ lookups ++;
+ currentPos++;
+
+ if( currentPos >= array.size( ) )
+ currentPos -= array.size( );
+ }
+
+ return currentPos;
+ }
+};
+
+#include "hmap.cpp"
+
+#endif
diff --git a/ychat-0.4/html.cpp b/ychat-0.4/html.cpp
new file mode 100755
index 0000000..f40e466
--- /dev/null
+++ b/ychat-0.4/html.cpp
@@ -0,0 +1,140 @@
+// class html implementation.
+
+#ifndef s_html_CXX
+#define s_html_CXX
+
+#include <fstream>
+#include "html.h"
+#include "s_chat.h"
+#include "s_mutx.h"
+
+using namespace std;
+
+html::html( )
+{
+ set_name( s_conf::get().get_val( "HTMLTEMP" ) );
+ pthread_mutex_init( &mut_map_vals, NULL );
+}
+
+html::~html( )
+{
+ pthread_mutex_destroy( &mut_map_vals );
+}
+
+void
+html::clear_cache( )
+{
+ pthread_mutex_lock ( &mut_map_vals );
+ clear_vals();
+ pthread_mutex_unlock( &mut_map_vals );
+}
+
+string
+html::parse( map_string &map_params )
+{
+ string s_file = map_params["request"];
+
+ // check if s_file is in the container.
+ pthread_mutex_lock ( &mut_map_vals );
+ string s_templ = get_val( s_file );
+ pthread_mutex_unlock( &mut_map_vals );
+
+ // if not, read file.
+ if ( s_templ.empty() )
+ {
+ auto string s_path = get_name();
+ auto ifstream fs_templ( s_path.append( s_file ).c_str(), ios::binary );
+
+ if ( ! fs_templ )
+ {
+
+ cerr << "File not found: " << s_file << endl;
+ if(map_params["request"]==s_conf::get().get_val( "NOTFOUND" ))
+ return "";
+
+ map_params["request"] = s_conf::get().get_val( "NOTFOUND" );
+ return parse( map_params );
+
+ }
+
+ auto char c_buf;
+ while( !fs_templ.eof() )
+ {
+ fs_templ.get( c_buf );
+ s_templ+=c_buf;
+ }
+
+ fs_templ.close();
+
+#ifdef VERBOSE
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cout << TECACHE << s_path << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+#endif
+
+ // cache file.
+ pthread_mutex_lock ( &mut_map_vals );
+ map_vals[ s_file ] = s_templ;
+ pthread_mutex_unlock( &mut_map_vals );
+ }
+
+ // find %%KEY%% token and substituate those.
+ auto unsigned int pos[2];
+ pos[0] = pos[1] = 0;
+
+ do
+ {
+ pos[0] = s_templ.find( "%%", pos[1] );
+
+ if ( pos[0] == string::npos )
+ break;
+
+ pos[0] += 2;
+ pos[1] = s_templ.find( "%%", pos[0] );
+
+ if ( pos[0] == string::npos )
+ break;
+
+ // get key and val.
+ auto string s_key = s_templ.substr( pos[0], pos[1]-pos[0] );
+ auto string s_val = s_conf::get().get_val( s_key );
+
+ // if s_val is empty use map_params.
+ if ( s_val.empty() )
+ s_val = map_params[ s_key ];
+
+ // substituate key with val.
+ s_templ.replace( pos[0]-2, pos[1]-pos[0]+4, s_val );
+
+ // calculate the string displacement.
+ auto int i_dif = s_val.length() - ( pos[1] - pos[0] + 4);
+
+ pos[1] += 2 + i_dif;
+
+ }
+ while( true );
+
+ return s_templ;
+}
+
+void
+html::online_list( user *p_user, map_string &map_params )
+{
+ // prepare user_list.
+ string s_list ( "" );
+ string s_seperator( "<br>" );
+
+ p_user->get_p_room()->get_user_list( s_list, s_seperator );
+
+ // use the collected data as a message in html-templates.
+ map_params["MESSAGE"] = s_list;
+
+ // renew the timestamp.
+ p_user->renew_stamp();
+
+ // send a ping to the client chat stream.
+ p_user->msg_post( new string("\n") );
+}
+
+#endif
+
diff --git a/ychat-0.4/html.h b/ychat-0.4/html.h
new file mode 100755
index 0000000..b43f0d2
--- /dev/null
+++ b/ychat-0.4/html.h
@@ -0,0 +1,42 @@
+// class html declaration. this class manages the html-template files.
+
+#ifndef s_html_H
+#define s_html_H
+
+#include "incl.h"
+#include "cont.h"
+#include "s_conf.h"
+#include "user.h"
+#include "name.h"
+
+
+using namespace std;
+
+class html : public cont, name
+{
+private:
+// needed for synchronizing the map_vals.
+ pthread_mutex_t mut_map_vals;
+
+public:
+ // public methods.
+ explicit html( ); // simple constructor.
+ ~html( );
+
+ // clears the template cache so that new html templates will be read
+ // from hard disk. this method is needed after changeing s.t. on
+ // the html-template files.
+ void clear_cache( );
+
+ // returns a parsed html-template. this method will check first if the
+ // required html-template exists inside the classes template cache. if not
+ // then the file will be read from file and added to the cache.
+ // afterwards the html-template will be parsed and returned.
+ // map_params contains the client request parameters which also will be
+ // used for string substituation.
+ virtual string parse( map_string &map_params );
+
+ virtual void online_list( user *p_user, map_string &map_params );
+};
+
+#endif
diff --git a/ychat-0.4/html/CVS/Entries b/ychat-0.4/html/CVS/Entries
new file mode 100644
index 0000000..12eb550
--- /dev/null
+++ b/ychat-0.4/html/CVS/Entries
@@ -0,0 +1,11 @@
+/blank.html/1.1.1.1/Fri Mar 21 15:54:56 2003//
+/frameset.html/1.1.1.1/Fri Mar 21 15:54:56 2003//
+/index.html/1.4/Sun Mar 30 00:34:08 2003//
+/input.html/1.2/Sun Mar 30 00:34:08 2003//
+/notfound.html/1.1.1.1/Fri Mar 21 15:54:56 2003//
+/online.html/1.2/Sun Mar 30 00:34:08 2003//
+/stream.html/1.2/Sun Mar 30 00:34:08 2003//
+/style.css/1.1/Sun Mar 30 11:12:49 2003//
+/y_ani.gif/1.1.1.1/Fri Mar 21 15:54:56 2003//
+/y_black.gif/1.1/Sun Mar 30 11:12:49 2003/-kb/
+D
diff --git a/ychat-0.4/html/CVS/Repository b/ychat-0.4/html/CVS/Repository
new file mode 100644
index 0000000..3648237
--- /dev/null
+++ b/ychat-0.4/html/CVS/Repository
@@ -0,0 +1 @@
+ychat/html
diff --git a/ychat-0.4/html/CVS/Root b/ychat-0.4/html/CVS/Root
new file mode 100644
index 0000000..2818c02
--- /dev/null
+++ b/ychat-0.4/html/CVS/Root
@@ -0,0 +1 @@
+:pserver:rover@cvs.ychat.berlios.de:/cvsroot/ychat
diff --git a/ychat-0.4/html/blank.html b/ychat-0.4/html/blank.html
new file mode 100755
index 0000000..4ddd1a7
--- /dev/null
+++ b/ychat-0.4/html/blank.html
@@ -0,0 +1,4 @@
+<html>
+ <body>
+ </body>
+</html>
diff --git a/ychat-0.4/html/frameset.html b/ychat-0.4/html/frameset.html
new file mode 100755
index 0000000..fe6b973
--- /dev/null
+++ b/ychat-0.4/html/frameset.html
@@ -0,0 +1,20 @@
+<html>
+<head>
+<title>
+ %%PGETITLE%%
+</title>
+</head>
+ <frameset rows="*,60">
+ <noframes>
+ Your browser does not support frames,
+ </noframes>
+ <frameset cols="*,150">
+ <frame src="stream.html?event=stream&nick=%%nick%%&tmpid=%%tmpid%%" name="stream">
+ <frame src="online.html?event=online&nick=%%nick%%&tmpid=%%tmpid%%" name="online">
+ </frameset>
+ <frameset rows="*,0">
+ <frame src="input.html?event=input&nick=%%nick%%&tmpid=%%tmpid%%" name="input">
+ <frame src="blank.html" name="blank">
+ </frameset>
+ </frameset>
+</html>
diff --git a/ychat-0.4/html/index.html b/ychat-0.4/html/index.html
new file mode 100755
index 0000000..7bc01b0
--- /dev/null
+++ b/ychat-0.4/html/index.html
@@ -0,0 +1,32 @@
+<html>
+<head>
+<title>
+ %%PGETITLE%%
+</title>
+<link rel=stylesheet href="style.css" type=text/css>
+</head>
+<body bgcolor=#000000 text=#ffff00>
+<table align=center width=500>
+<tr>
+<td align=center><img src="y_black.gif" alt="ychat"></td>
+<td align=center class=header>%%PGETITLE%%<br>%%INFO%%</td>
+</tr>
+<tr>
+ <td colspan=2>&nbsp;</td>
+</tr>
+<tr>
+ <td align=center colspan=2>
+Enter your nick:
+<form action="frameset.html" method="GET">
+ <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>
+</td>
+</tr>
+</table>
+<br><br>
+<center><span class="signature">yChat is OpenSource - get it at <a target="_blank" href="http://www.yChat.org">http://www.yChat.org</a></span></center>
+</body>
+</html>
diff --git a/ychat-0.4/html/input.html b/ychat-0.4/html/input.html
new file mode 100755
index 0000000..a403d8e
--- /dev/null
+++ b/ychat-0.4/html/input.html
@@ -0,0 +1,34 @@
+<html>
+ <head>
+ <title>
+ %%PGETITLE%%
+ </title>
+<link rel=stylesheet href="style.css" type=text/css>
+
+ <script language="JavaScript">
+ <!--
+ function delout()
+ {
+ document.input.message.focus();
+ document.input.message.select();
+ document.input.submit();
+ return false;
+ }
+ function selectinput()
+ {
+ document.input.message.select();
+ }
+ //-->
+ </script>
+ </head>
+ <body bgcolor=#000000 text=#ffffff>
+ <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%%">
+ <input type="hidden" name="tmpid" value="%%tmpid%%">
+ <input type="text" name="message" size="50">
+ <input type="submit" value="send">
+ <input type="button" value="select" onclick="javascript:selectinput();">
+ </form>
+ </body>
+</html>
diff --git a/ychat-0.4/html/notfound.html b/ychat-0.4/html/notfound.html
new file mode 100755
index 0000000..574e341
--- /dev/null
+++ b/ychat-0.4/html/notfound.html
@@ -0,0 +1,10 @@
+<html>
+<head>
+<title>
+ %%PGETITLE%%
+</title>
+</head>
+<body>
+ Page not found.
+</body>
+</html>
diff --git a/ychat-0.4/html/online.html b/ychat-0.4/html/online.html
new file mode 100755
index 0000000..aa14f8d
--- /dev/null
+++ b/ychat-0.4/html/online.html
@@ -0,0 +1,7 @@
+<html>
+ <meta http-equiv="refresh" content="20">
+<link rel=stylesheet href="style.css" type=text/css>
+ <body bgcolor=#000000 text=#ffffff>
+ %%MESSAGE%%
+ </body>
+</html>
diff --git a/ychat-0.4/html/stream.html b/ychat-0.4/html/stream.html
new file mode 100755
index 0000000..6678069
--- /dev/null
+++ b/ychat-0.4/html/stream.html
@@ -0,0 +1,30 @@
+<html>
+ <head>
+ <title>
+ %%PGETITLE%%
+ </title>
+<link rel=stylesheet href="style.css" type=text/css>
+ <script language="JavaScript">
+ function autoScroll()
+ {
+ window.scroll(1, 50000 );
+ timer = setTimeout('autoScroll()',200);
+ }
+
+ autoScroll();
+
+ function stopScroll()
+ {
+ clearTimeout(timer);
+ }
+
+ function startScroll()
+ {
+ timer = setTimeout('autoScroll()', 200);
+ }
+ </script>
+</head>
+<body bgcolor=#000000 text=#ffffff>
+ Welcome to yChat %%nick%%!
+ <br>
+ <br>
diff --git a/ychat-0.4/html/style.css b/ychat-0.4/html/style.css
new file mode 100644
index 0000000..e31bd7e
--- /dev/null
+++ b/ychat-0.4/html/style.css
@@ -0,0 +1,11 @@
+BODY, TD {
+ font-family: Verdana, Helvetica, sans-serif;
+ font-size: 11pt;
+}
+A {
+ color: #dddddd;
+}
+.signature {
+ color: #dddddd;
+ font-size: 9pt;
+}
diff --git a/ychat-0.4/html/y_ani.gif b/ychat-0.4/html/y_ani.gif
new file mode 100755
index 0000000..e730988
--- /dev/null
+++ b/ychat-0.4/html/y_ani.gif
Binary files differ
diff --git a/ychat-0.4/html/y_black.gif b/ychat-0.4/html/y_black.gif
new file mode 100755
index 0000000..06274c2
--- /dev/null
+++ b/ychat-0.4/html/y_black.gif
Binary files differ
diff --git a/ychat-0.4/incl.h b/ychat-0.4/incl.h
new file mode 100755
index 0000000..f8e483f
--- /dev/null
+++ b/ychat-0.4/incl.h
@@ -0,0 +1,16 @@
+// contains header files which are included by all classes.
+
+// include some std headers.
+#include <iostream>
+
+// since thread synchronization is a big issue this header needs
+// to be included by every other file too.
+#include <pthread.h>
+
+// std::string.
+#include <string>
+
+// include all the custom global variables.
+#include "glob.h"
+// include all the custom messages.
+#include "msgs.h"
diff --git a/ychat-0.4/lang.cpp b/ychat-0.4/lang.cpp
new file mode 100755
index 0000000..b5b33ec
--- /dev/null
+++ b/ychat-0.4/lang.cpp
@@ -0,0 +1,78 @@
+// class conf implementation.
+
+#ifndef s_lang_CXX
+#define s_lang_CXX
+
+#include <fstream>
+#include "lang.h"
+
+using namespace std;
+
+lang::lang( string s_lang = "en" ) : name( s_lang )
+{
+ parse( ); // parse the config file.
+}
+
+lang::~lang()
+{
+}
+
+void
+lang::parse()
+{
+#ifdef VERBOSE
+ cout << CFILEOK << get_name() << endl;
+#endif
+
+ string filename("lang/");
+ filename.append(get_name());
+
+ ifstream fs_conf( filename.c_str() );
+
+ if ( ! fs_conf )
+ {
+#ifdef VERBOSE
+ cout << CFILENO << get_name() << endl;
+#endif
+ return;
+ }
+
+ char c_buf[READBUF];
+
+ while( fs_conf.getline( c_buf, READBUF ) )
+ {
+ string s_token( c_buf );
+ unsigned int ui_pos = s_token.find( "#", 0 );
+
+ // if line is commented out:
+ if ( ui_pos == 0 )
+ continue;
+
+ ui_pos = s_token.find( ";", 0 );
+
+ // if token has not been found.
+ if ( ui_pos == string::npos )
+ continue;
+
+ s_token = s_token.substr( 0 , --ui_pos );
+ ui_pos = s_token.find ( "\"", 0 );
+
+ if ( ui_pos == string::npos )
+ continue;
+
+ string s_val = s_token.substr( ui_pos+1, s_token.length() );
+ string s_key = s_token.substr( 0 , --ui_pos );
+
+#ifdef VERBOSE2
+ cout << s_key << "=" << s_val << endl;
+#endif
+
+ // fill the map.
+ map_vals[s_key] = s_val;
+ }
+
+ fs_conf.close();
+ fs_conf.~ifstream();
+}
+
+#endif
diff --git a/ychat-0.4/lang.h b/ychat-0.4/lang.h
new file mode 100755
index 0000000..6745a93
--- /dev/null
+++ b/ychat-0.4/lang.h
@@ -0,0 +1,24 @@
+// class conf declaration. this class parses the server config file.
+
+#ifndef s_lang_H
+#define s_lang_H
+
+#include "incl.h"
+#include "cont.h"
+#include "name.h"
+
+using namespace std;
+
+class lang : public cont, name
+{
+private:
+
+public:
+ // public methods:
+ lang ( string s_lang ); // standard constructor.
+ ~lang(); // standard destructor.
+
+ virtual void parse( ); // parses the config file.
+};
+
+#endif
diff --git a/ychat-0.4/lang/CVS/Entries b/ychat-0.4/lang/CVS/Entries
new file mode 100644
index 0000000..609d13c
--- /dev/null
+++ b/ychat-0.4/lang/CVS/Entries
@@ -0,0 +1,3 @@
+/de/1.1/Fri Apr 4 22:14:35 2003//
+/en/1.1/Fri Apr 4 22:14:35 2003//
+D
diff --git a/ychat-0.4/lang/CVS/Repository b/ychat-0.4/lang/CVS/Repository
new file mode 100644
index 0000000..9dd3b40
--- /dev/null
+++ b/ychat-0.4/lang/CVS/Repository
@@ -0,0 +1 @@
+ychat/lang
diff --git a/ychat-0.4/lang/CVS/Root b/ychat-0.4/lang/CVS/Root
new file mode 100644
index 0000000..2818c02
--- /dev/null
+++ b/ychat-0.4/lang/CVS/Root
@@ -0,0 +1 @@
+:pserver:rover@cvs.ychat.berlios.de:/cvsroot/ychat
diff --git a/ychat-0.4/lang/de b/ychat-0.4/lang/de
new file mode 100644
index 0000000..ae5404b
--- /dev/null
+++ b/ychat-0.4/lang/de
@@ -0,0 +1,3 @@
+ERRORCMD="<font color=#ff0000>Befehl nicht gefunden!</font><br>";
+USERENTR=" betritt den Chat.<br>";
+USERLEAV=" verl&auml;&szlig;t den Chat.<br>"
diff --git a/ychat-0.4/lang/en b/ychat-0.4/lang/en
new file mode 100644
index 0000000..33e9b52
--- /dev/null
+++ b/ychat-0.4/lang/en
@@ -0,0 +1,3 @@
+ERRORCMD=" <font color='#FF0000'>No such command!</font><br>";
+USERENTR=" enters the chat<br>";
+USERLEAV=" leaves the chat<br>";
diff --git a/ychat-0.4/logd.cpp b/ychat-0.4/logd.cpp
new file mode 100644
index 0000000..cfdc7c6
--- /dev/null
+++ b/ychat-0.4/logd.cpp
@@ -0,0 +1,65 @@
+#ifndef LOGD_CXX
+#define LOGD_CXX
+
+#include "logd.h"
+
+logd::logd( string filename )
+{
+ if(filename.empty())
+ {
+ cerr << "ycLog: No filename specified" << endl;
+ exit(1);
+ }
+
+ s_logfile=filename;
+
+ i_lines=s_tool::string2int( s_conf::get().get_val("LOG_LINES"));
+
+}
+void logd::flush()
+{
+ s_output.open(s_logfile.c_str(), ios::app);
+
+ if(s_output==NULL)
+ {
+ cerr << "ycLog: Could not open file: " << s_logfile << endl;
+ exit(1);
+ }
+
+
+ while(!s_queue.empty())
+ {
+ string s_l=s_queue.front();
+ s_queue.pop();
+ s_output.write(s_l.c_str(), s_l.size());
+
+ }
+ s_output.close();
+}
+void logd::log( map_string request )
+{
+ struct tm *t_m;
+ time_t t_cur=time(NULL);
+ t_m=gmtime(&t_cur);
+
+ char buffer[100];
+ strftime(buffer, 100, "[%d/%b/%Y:%H:%M:%S %z]", t_m);
+ string s_time=buffer;
+ string s_logstr = request["REMOTE_ADDR"] + " - - "+s_time+" \"" + request["QUERY_STRING"]+"\" 200 0 \""+request["request"]+"\" \""+request["User-Agent"]+"\"\n";
+
+ s_queue.push(s_logstr);
+
+ if(s_queue.size()>=i_lines)
+ flush();
+}
+
+logd::~logd()
+{
+ flush();
+}
+
+
+
+
+
+#endif
diff --git a/ychat-0.4/logd.h b/ychat-0.4/logd.h
new file mode 100644
index 0000000..5d79d9d
--- /dev/null
+++ b/ychat-0.4/logd.h
@@ -0,0 +1,24 @@
+#ifndef LOGD_H
+#define LOGD_H
+
+#include "incl.h"
+#include "s_tool.h"
+#include "s_conf.h"
+#include <fstream>
+#include <queue>
+#include <time.h>
+class logd {
+
+ private:
+ string s_logfile;
+ queue<string> s_queue;
+ ofstream s_output;
+ int i_lines;
+ public:
+ logd( string filename );
+ ~logd();
+
+ void flush();
+ void log( map_string request );
+};
+#endif
diff --git a/ychat-0.4/main.cpp b/ychat-0.4/main.cpp
new file mode 100755
index 0000000..08f89f8
--- /dev/null
+++ b/ychat-0.4/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/ychat-0.4/modl.cpp b/ychat-0.4/modl.cpp
new file mode 100755
index 0000000..17c7b49
--- /dev/null
+++ b/ychat-0.4/modl.cpp
@@ -0,0 +1,98 @@
+// class modl implementation.
+
+#ifndef MODL_CXX
+#define MODL_CXX
+
+#include <limits.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <stdio.h>
+
+#include "s_mutx.h"
+#include "modl.h"
+
+using namespace std;
+
+modl::modl( )
+{
+ map_mods = new hmap<dynmod*,string>(80);
+ pthread_mutex_init( &mut_map_mods, NULL );
+}
+
+modl::~modl()
+{
+ pthread_mutex_lock ( &mut_map_mods );
+
+ // dlclose all the_module's first!
+ map_mods->run_func ( &modl::dlclose_ );
+
+ // then clean the hash map.
+ map_mods->make_empty ( );
+
+ pthread_mutex_unlock ( &mut_map_mods );
+ pthread_mutex_destroy( &mut_map_mods );
+}
+
+void
+modl::dlclose_( dynmod* mod )
+{
+ dlclose( mod->the_module );
+}
+
+dynmod*
+modl::cache_module( string s_name )
+{
+ void *the_module = NULL;
+ function *the_func = NULL;
+
+ the_module = dlopen( s_name.c_str(), RTLD_NOW );
+
+ if ( the_module == NULL )
+ {
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cerr << "dlerror: " << dlerror() << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+ return NULL;
+ }
+
+ the_func = (function*) dlsym( the_module, "extern_function" );
+
+ if ( the_func == NULL )
+ {
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cerr << "dlerror: " << dlerror() << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+ return NULL;
+ }
+
+#ifdef VERBOSE
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cout << MODULEC << s_name << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+#endif
+
+ dynmod *mod = new dynmod; // encapsulates the function and module handler.
+ mod->the_func = the_func ; // the function to execute
+ mod->the_module = the_module; // the module handler to close if function
+ // is not needed anymore.
+ pthread_mutex_lock ( &mut_map_mods );
+ map_mods->add_elem ( mod, s_name );
+ pthread_mutex_unlock( &mut_map_mods );
+
+// DO NOT CLOSE AS LONG THERE EXIST A POINTER TO THE FUNCTION
+// dlclose( module );
+
+ return mod;
+}
+
+dynmod*
+modl::get_module( string s_name )
+{
+ pthread_mutex_lock ( &mut_map_mods );
+ dynmod* mod = map_mods->get_elem( s_name );
+ pthread_mutex_unlock( &mut_map_mods );
+
+ return ! mod ? cache_module( s_name ) : mod;
+}
+
+#endif
diff --git a/ychat-0.4/modl.h b/ychat-0.4/modl.h
new file mode 100755
index 0000000..10f93ba
--- /dev/null
+++ b/ychat-0.4/modl.h
@@ -0,0 +1,29 @@
+// class modl declaration.
+
+#ifndef MODL_H
+#define MODL_H
+
+#include "incl.h"
+#include "hmap.h"
+
+using namespace std;
+
+
+class modl
+{
+private:
+ hmap<dynmod*,string>* map_mods;
+ pthread_mutex_t mut_map_mods;
+
+ static void dlclose_( dynmod* mod );
+ dynmod* cache_module ( string s_name );
+
+public:
+ modl();
+ ~modl();
+
+ dynmod* get_module ( string s_name );
+
+};
+
+#endif
diff --git a/ychat-0.4/msgs.h b/ychat-0.4/msgs.h
new file mode 100755
index 0000000..1f6e1da
--- /dev/null
+++ b/ychat-0.4/msgs.h
@@ -0,0 +1,36 @@
+#ifndef MSGS_H
+#define MSGS_H
+
+
+// several error messages which will apear by the clients.
+#define E_ALPNUM "The nick you have specified is not alphanumeric, please change that.<br><br>"
+#define E_NONICK "You need to specify a nick name.<br><br>"
+#define E_NOTONL "An error occured. Your nick is not online.<br><br>"
+#define E_ONLINE "The nick you have specified is already online. Try another nick.<br><br>"
+
+// all the custom messages for verbosity outputs. this messages may not
+// be used for html-template value substituation except the CONTACT and
+// DESCRIP variables. the verbosity output will appear in the standard
+// output of the server.
+// alphabetical ordered.
+#define CFILEOK "Parsing config file "
+#define CFILENO "Failed opening config file "
+#define CONNECT "Receiving connection "
+#define CONTACT "Contact: www.yChat.org, Mail@yChat.org "
+#define DESCRIP "yChat++ Copyright (C) 2003 Paul C. Buetow, Volker Richer "
+#define DOWNMSG "Shutting down "
+#define LOGINPR "Login procedure succeeded for nick "
+#define MODULEC "Caching module "
+#define NEWROOM "Adding room "
+#define REQUEST "Request string "
+#define SEPERAT "----------------------------------------- "
+#define SOCKCRT "Creating server socket "
+#define SOCKERR "Could not create socket. Trying next port "
+#define SOCKRDY "Server socket is ready. See port above "
+#define STARTMS "Starting up "
+#define TECACHE "Caching template "
+#define THREADS "Starting thread job "
+#define THREADE "Exiting thread job "
+#define VERSION "Version: 0.4"
+
+#endif
diff --git a/ychat-0.4/mutx.cpp b/ychat-0.4/mutx.cpp
new file mode 100755
index 0000000..eb75e90
--- /dev/null
+++ b/ychat-0.4/mutx.cpp
@@ -0,0 +1,20 @@
+// class mutx implementation.
+
+#ifndef s_mutx_CXX
+#define s_mutx_CXX
+
+#include "mutx.h"
+
+using namespace std;
+
+mutx::mutx()
+{
+ pthread_mutex_init( &mut_stdout, NULL );
+}
+
+mutx::~mutx()
+{
+ pthread_mutex_destroy( &mut_stdout );
+}
+
+#endif
diff --git a/ychat-0.4/mutx.h b/ychat-0.4/mutx.h
new file mode 100755
index 0000000..0438cb9
--- /dev/null
+++ b/ychat-0.4/mutx.h
@@ -0,0 +1,21 @@
+// class mutx declaration.
+
+#ifndef s_mutx_H
+#define s_mutx_H
+
+#include "incl.h"
+
+using namespace std;
+
+class mutx
+{
+public:
+ // this mutex is needed for sync stdout and sdterr of different threads.
+ pthread_mutex_t mut_stdout;
+
+ // public methods.
+ explicit mutx( ); // simple constructor.
+ ~mutx( ); // simple constructor.
+};
+
+#endif
diff --git a/ychat-0.4/name.cpp b/ychat-0.4/name.cpp
new file mode 100755
index 0000000..28033ff
--- /dev/null
+++ b/ychat-0.4/name.cpp
@@ -0,0 +1,32 @@
+// class name implementation.
+
+#ifndef NAME_CXX
+#define NAME_CXX
+
+#include "name.h"
+
+using namespace std;
+
+name::name( string s_name )
+{
+ set_name( s_name );
+}
+
+name::~name()
+{
+}
+
+string
+name::get_name() const
+{
+ return s_name;
+}
+
+void
+name::set_name( string s_name )
+{
+ this->s_name = s_name;
+}
+
+
+#endif
diff --git a/ychat-0.4/name.h b/ychat-0.4/name.h
new file mode 100755
index 0000000..b895389
--- /dev/null
+++ b/ychat-0.4/name.h
@@ -0,0 +1,28 @@
+// class name declaration.
+
+#ifndef NAME_H
+#define NAME_H
+
+#include "incl.h"
+
+using namespace std;
+
+class name
+{
+protected:
+ // private members:
+ string s_name; // object's name.
+
+public:
+ virtual string get_name ( ) const;
+ virtual void set_name ( string s_name );
+
+
+ // public methods:
+ explicit name( ) { }; // a standard constructor.
+ explicit name( string s_name ); // a standard constructor.
+ ~name( );
+
+};
+
+#endif
diff --git a/ychat-0.4/pool.cpp b/ychat-0.4/pool.cpp
new file mode 100755
index 0000000..470ea24
--- /dev/null
+++ b/ychat-0.4/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;
+ pthread_cond_signal( &(tpool->queue_not_empty) );
+ }
+
+ else
+ {
+ tpool->queue_tail->next = workp;
+ tpool->queue_tail = workp;
+ }
+
+ tpool->cur_queue_size++;
+ pthread_mutex_unlock( &(tpool->queue_lock) );
+ return 1;
+}
+
+#endif
diff --git a/ychat-0.4/pool.h b/ychat-0.4/pool.h
new file mode 100755
index 0000000..358b79f
--- /dev/null
+++ b/ychat-0.4/pool.h
@@ -0,0 +1,77 @@
+// class pool declaration.
+
+#ifndef POOL_H
+#define POOL_H
+
+#include "incl.h"
+
+using namespace std;
+
+class pool
+{
+private:
+ typedef struct tpool_work
+ {
+ void (*routine)(void*); ///
+ void *arg;
+ struct tpool_work *next;
+ }
+ tpool_work_t;
+
+ typedef struct tpool
+ {
+ // pool characteristics:
+ int num_threads;
+ int max_queue_size;
+ int do_not_block_when_full;
+
+ // pool state
+ pthread_t *threads;
+ int cur_queue_size;
+
+ tpool_work_t *queue_head;
+ tpool_work_t *queue_tail;
+
+ pthread_mutex_t queue_lock;
+ pthread_cond_t queue_not_empty;
+ pthread_cond_t queue_not_full;
+ pthread_cond_t queue_empty;
+
+ int queue_closed;
+ int shutdown;
+ }
+ *tpool_t;
+
+ int i_thrd_pool_size;
+ int i_thrd_pool_queue;
+
+ tpool_t thread_pool;
+
+ virtual void
+ tpool_init( tpool_t *tpoolp, int num_worker_threads, int max_queue_size, int do_not_block_when_full );
+
+ virtual int
+ tpool_add_work( tpool_t tpool, void(*routine)(void*), void* arg );
+
+// virtual void
+// tpool_destroy( tpool_t tpoolp, int finish );
+
+ static void*
+ tpool_thread( void* arg);
+
+ static void
+ run_func( void *v_pointer );
+
+ // public methods:
+public:
+ explicit pool( );
+ ~pool();
+
+ // inline (speed)!
+ void run( void *arg )
+ {
+ tpool_add_work( thread_pool, run_func, arg );
+ }
+};
+
+#endif
diff --git a/ychat-0.4/reqp.cpp b/ychat-0.4/reqp.cpp
new file mode 100755
index 0000000..4d184c8
--- /dev/null
+++ b/ychat-0.4/reqp.cpp
@@ -0,0 +1,281 @@
+// 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 = "Cache-control: 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];
+ 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;
+
+ 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
+
+ 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");
+ 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"].
+ get_url( p_thrd, s_req, map_params );
+ 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("\n\n");
+
+ // check the event variable.
+
+ string s_event( map_params["event"] );
+ if ( ! s_event.empty() )
+ {
+ // login procedure.
+ if ( s_event == "login" )
+ {
+ s_chat::get().login( map_params );
+ }
+
+ else
+ {
+ bool b_found;
+
+// user* p_user = s_chat::get().get_user( map_params["nick"], b_found );
+ sess *sess_temp=s_sman::get().getSession( map_params["tmpid"] );
+ user *p_user;
+ if(sess_temp!=NULL)
+ {
+ string *s_nick=static_cast<string*>(sess_temp->getValue(string("nick")));
+ p_user = s_chat::get().get_user( *s_nick, b_found);
+ }
+ else
+ return s_rep;
+ if ( ! b_found )
+ {
+ map_params["INFO"] = E_NOTONL;
+ map_params["request"] = s_conf::get().get_val( "STARTMPL" ); // redirect to the startpage.
+ }
+ // if a message post.
+ else if ( s_event == "post" )
+ s_chat::get().post( p_user, map_params );
+
+
+ // if a chat stream
+ else if ( s_event == "stream" )
+ {
+ string s_msg(s_html::get().parse( map_params ) );
+ p_user->msg_post( &s_msg);
+ s_sock::get().chat_stream( p_thrd->get_sock(), p_user, map_params );
+ }
+
+ // if a request for the online list of the active room.
+ else if ( s_event == "online" )
+ s_html::get().online_list( p_user, map_params );
+ }
+ }
+
+ // parse and get the requested html-template and also use
+ // the values stored in map_params for %%KEY%% substituations.
+ s_rep.append( s_html::get().parse( map_params ) );
+
+ // return the parsed html-template.
+ return s_rep;
+}
+
+#endif
diff --git a/ychat-0.4/reqp.h b/ychat-0.4/reqp.h
new file mode 100755
index 0000000..399c751
--- /dev/null
+++ b/ychat-0.4/reqp.h
@@ -0,0 +1,47 @@
+// class reqp declaration. this class parses the client requests.
+
+#ifndef REQP_H
+#define REQP_H
+
+#define RQ_GET 1
+#define RQ_POST 2
+
+#include <map>
+#include "incl.h"
+#include "thrd.h"
+
+using namespace std;
+
+typedef map<string, string, less<string> > map_string;
+
+class reqp
+{
+private:
+ static string HTTP_CODEOK,
+ HTTP_CODENF,
+ HTTP_SERVER,
+ HTTP_CONTAC,
+ HTTP_CACHEC,
+ HTTP_CONNEC,
+ HTTP_COTYPE;
+
+ // returns the request url from thr client's http request header
+ // until the first "?" and stores all request parameter values
+ // ( behind "?" ) into map_params.
+ virtual string get_url( thrd* p_thrd, string s_req, map_string &map_params );
+ // returns a specific value of the client's http request header.
+ // ( s.t. like the User-Agent, Referer etc... ).
+ virtual string get_from_header( string s_req, string s_hdr );
+
+ virtual int htoi( string *s );
+
+public:
+ // public methods.
+ explicit reqp( ); // simple constructor.
+ virtual string parse( thrd* p_thrd, string s_req, map_string &map_params );
+ virtual string url_decode ( string );
+ virtual string get_content_type( string );
+ virtual void parse_headers( string s_req, map_string &map_params );
+};
+
+#endif
diff --git a/ychat-0.4/room.cpp b/ychat-0.4/room.cpp
new file mode 100755
index 0000000..0e905e6
--- /dev/null
+++ b/ychat-0.4/room.cpp
@@ -0,0 +1,18 @@
+// class room implementation.
+
+#ifndef ROOM_CXX
+#define ROOM_CXX
+
+#include "room.h"
+
+using namespace std;
+
+room::room( string s_name ) : name( s_name )
+{
+}
+
+room::~room()
+{
+}
+
+#endif
diff --git a/ychat-0.4/room.h b/ychat-0.4/room.h
new file mode 100755
index 0000000..f351b9a
--- /dev/null
+++ b/ychat-0.4/room.h
@@ -0,0 +1,34 @@
+// class room declaration.
+
+#ifndef ROOM_H
+#define ROOM_H
+
+#include "incl.h"
+#include "base.h"
+#include "name.h"
+#include "user.h"
+
+using namespace std;
+
+class room : public base<user>, public name
+{
+private:
+
+public:
+ void add_user( user* p_user )
+ {
+ p_user->set_p_room( this );
+ add_elem( p_user );
+ }
+
+ user* get_user( string &s_name, bool &b_found )
+ {
+ return static_cast<user*>( get_elem( s_name, b_found ) );
+ }
+
+ // public methods:
+ explicit room( string s_name ); // a constructor.
+ ~room(); // room destructor.
+};
+
+#endif
diff --git a/ychat-0.4/s_chat.cpp b/ychat-0.4/s_chat.cpp
new file mode 100644
index 0000000..9e0d01b
--- /dev/null
+++ b/ychat-0.4/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/ychat-0.4/s_chat.h b/ychat-0.4/s_chat.h
new file mode 100644
index 0000000..4162180
--- /dev/null
+++ b/ychat-0.4/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/ychat-0.4/s_conf.cpp b/ychat-0.4/s_conf.cpp
new file mode 100644
index 0000000..ea1c05a
--- /dev/null
+++ b/ychat-0.4/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/ychat-0.4/s_conf.h b/ychat-0.4/s_conf.h
new file mode 100644
index 0000000..09c4ea7
--- /dev/null
+++ b/ychat-0.4/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/ychat-0.4/s_html.cpp b/ychat-0.4/s_html.cpp
new file mode 100644
index 0000000..0899abe
--- /dev/null
+++ b/ychat-0.4/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/ychat-0.4/s_html.h b/ychat-0.4/s_html.h
new file mode 100644
index 0000000..af8297b
--- /dev/null
+++ b/ychat-0.4/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/ychat-0.4/s_lang.cpp b/ychat-0.4/s_lang.cpp
new file mode 100644
index 0000000..41c2089
--- /dev/null
+++ b/ychat-0.4/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/ychat-0.4/s_lang.h b/ychat-0.4/s_lang.h
new file mode 100644
index 0000000..03851b9
--- /dev/null
+++ b/ychat-0.4/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/ychat-0.4/s_modl.cpp b/ychat-0.4/s_modl.cpp
new file mode 100644
index 0000000..f6a5913
--- /dev/null
+++ b/ychat-0.4/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/ychat-0.4/s_modl.h b/ychat-0.4/s_modl.h
new file mode 100644
index 0000000..b5267dd
--- /dev/null
+++ b/ychat-0.4/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/ychat-0.4/s_mutx.cpp b/ychat-0.4/s_mutx.cpp
new file mode 100644
index 0000000..33c8385
--- /dev/null
+++ b/ychat-0.4/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/ychat-0.4/s_mutx.h b/ychat-0.4/s_mutx.h
new file mode 100644
index 0000000..24c0f97
--- /dev/null
+++ b/ychat-0.4/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/ychat-0.4/s_sman.cpp b/ychat-0.4/s_sman.cpp
new file mode 100644
index 0000000..bfb1efd
--- /dev/null
+++ b/ychat-0.4/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/ychat-0.4/s_sman.h b/ychat-0.4/s_sman.h
new file mode 100644
index 0000000..ff3a7c5
--- /dev/null
+++ b/ychat-0.4/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/ychat-0.4/s_sock.cpp b/ychat-0.4/s_sock.cpp
new file mode 100644
index 0000000..dd80e71
--- /dev/null
+++ b/ychat-0.4/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/ychat-0.4/s_sock.h b/ychat-0.4/s_sock.h
new file mode 100644
index 0000000..d570e0c
--- /dev/null
+++ b/ychat-0.4/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/ychat-0.4/s_tool.cpp b/ychat-0.4/s_tool.cpp
new file mode 100644
index 0000000..ae6357a
--- /dev/null
+++ b/ychat-0.4/s_tool.cpp
@@ -0,0 +1,111 @@
+#ifndef s_tool_CXX
+#define s_tool_CXX
+
+#include <ctype.h>
+#include <time.h>
+#include "s_tool.h"
+
+bool
+s_tool::is_alpha_numeric( string &s_digit )
+{
+ auto const char *digit = s_digit.c_str();
+ auto int i_len = strlen( digit );
+
+ for( int i=0; i<i_len; i++ )
+ {
+ if ( ! isalnum( *digit ) )
+ return false;
+ digit++;
+ }
+
+ return true;
+}
+string
+s_tool::trim( string s_str )
+{
+ if(s_str.empty())return "";
+ char c_cur=s_str[0];
+ auto int pos=0;
+// left trim
+ while(c_cur==' ' || c_cur == '\n' || c_cur == '\r')
+ {
+ s_str.erase(pos,1);
+
+ c_cur=s_str[++pos];
+
+ }
+// right trim
+
+ pos=s_str.size();
+ c_cur=s_str[s_str.size()];
+
+ while(c_cur==' ' || c_cur == '\n' || c_cur == '\0' || c_cur == '\r')
+ {
+ s_str.erase(pos,1);
+ c_cur=s_str[--pos];
+
+ }
+ return s_str;
+}
+
+string
+s_tool::getExtension( string s_file )
+{
+ int pos = s_file.find_last_of(".");
+ if(pos != string::npos)
+ {
+ string s_ext=s_file.substr(pos+1, s_file.size()-(pos+1));
+ for(int i = 0;i<s_ext.size();i++)
+ s_ext[i]=toupper(s_ext[i]);
+ return s_ext;
+ }
+ return "";
+}
+
+int
+s_tool::string2int( string s_digit )
+{
+ auto const char *digit = s_digit.c_str();
+ int result = 0;
+
+ // Convert each digit char and add into result.
+ while (*digit >= '0' && *digit <='9') {
+ result = (result * 10) + (*digit - '0');
+ digit++;
+ }
+
+ // Check that there were no non-digits at end.
+ if (*digit != 0) {
+ return -1;
+ }
+
+ return result;
+}
+
+long
+s_tool::unixtime()
+{
+ return (long) time( NULL );
+}
+
+
+void
+s_tool::strip_html( string *s_str )
+{
+ auto int i_pos;
+
+ if((i_pos=s_str->find("<",0))==string::npos)
+ return;
+ while(true)
+ {
+
+ s_str->replace(i_pos,1,"&lt;");
+
+ if((i_pos=s_str->find("<",0))==string::npos)
+ return;
+
+ }
+
+
+}
+#endif
diff --git a/ychat-0.4/s_tool.h b/ychat-0.4/s_tool.h
new file mode 100644
index 0000000..f778c37
--- /dev/null
+++ b/ychat-0.4/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/ychat-0.4/sess.cpp b/ychat-0.4/sess.cpp
new file mode 100644
index 0000000..10c4c8f
--- /dev/null
+++ b/ychat-0.4/sess.cpp
@@ -0,0 +1,35 @@
+#ifndef SESS_CPP
+#define SESS_CPP
+
+#include "sess.h"
+
+sess::sess( string s_id )
+{
+ this->sess_id=s_id;
+}
+
+string sess::getId(){ return this->sess_id; }
+
+
+void sess::invalidate() {
+ this->sess_id="0";
+ this->sess_values.clear();
+}
+
+void sess::setValue( string s_key, void *lpvalue )
+{
+ this->sess_values[s_key]=lpvalue;
+}
+void *sess::getValue( string s_key )
+{
+ return this->sess_values[s_key];
+}
+string sess::dump()
+{
+ string s_ret=string("Session Dump of Session ") + this->getId();
+ map<string, void*>::const_iterator it;
+ for(it=this->sess_values.begin();it!=this->sess_values.end();it++)
+ s_ret=s_ret + "\nkey: " + it->first;
+ return s_ret;
+}
+#endif
diff --git a/ychat-0.4/sess.h b/ychat-0.4/sess.h
new file mode 100644
index 0000000..8d7b08e
--- /dev/null
+++ b/ychat-0.4/sess.h
@@ -0,0 +1,28 @@
+#ifndef s_sess_H
+#define s_sess_H
+
+#include "incl.h"
+#include "cont.h"
+#include "name.h"
+#include <map>
+#include <string>
+#include "hmap.h"
+using namespace std;
+
+typedef map<string, void *> sess_map;
+
+class sess : public cont, name
+{
+
+ private:
+ sess_map sess_values;
+ string sess_id;
+ public:
+ sess(string s_id);
+ string getId();
+ void setValue(string s_key, void *lpvalue);
+ void *getValue( string s_key );
+ void invalidate();
+ string dump();
+};
+#endif
diff --git a/ychat-0.4/sman.cpp b/ychat-0.4/sman.cpp
new file mode 100644
index 0000000..4c95b32
--- /dev/null
+++ b/ychat-0.4/sman.cpp
@@ -0,0 +1,48 @@
+#ifndef SMAN_CXX
+#define SMAN_CXX
+
+#include "sman.h"
+
+sman::sman()
+{
+ this->sessions=new hmap<sess *, string>(80);
+ this->sessioncount=0;
+}
+sman::~sman()
+{
+ delete this->sessions;
+}
+string sman::generateId( int len )
+{
+ string valid_chars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
+ string s_ret="";
+ srand(time(0)+160682);
+ for(int i=0;i<len;i++)
+ {
+ int i_char=rand() % 64;
+ s_ret+=valid_chars[i_char];
+ }
+ return s_ret;
+}
+sess *sman::createSession( )
+{
+ string new_id=this->generateId(s_tool::string2int( s_conf::get().get_val( "SESSION_LENGTH" ) ) );
+
+ sess *new_sess= new sess( new_id );
+
+ this->sessioncount++;
+ this->sessions->add_elem( new_sess, new_id );
+
+ return new_sess;
+}
+
+sess *sman::getSession( string s_id )
+{
+ return this->sessions->get_elem( s_id );
+}
+void sman::destroySession( string s_id )
+{
+ this->sessioncount--;
+ this->sessions->del_elem( s_id );
+}
+#endif
diff --git a/ychat-0.4/sman.h b/ychat-0.4/sman.h
new file mode 100644
index 0000000..336bdf1
--- /dev/null
+++ b/ychat-0.4/sman.h
@@ -0,0 +1,32 @@
+#ifndef SMAN_H
+#define SMAN_H
+
+#include "incl.h"
+#include "hmap.h"
+#include "sess.h"
+#include "s_tool.h"
+#include "s_conf.h"
+#include <cstdlib>
+
+using namespace std;
+
+class sman{
+
+ private:
+ hmap<sess *, string> *sessions;
+ string generateId( int len );
+ int sessioncount;
+ public:
+ sman();
+ ~sman();
+ sess *getSession( string s_id );
+ int getSessionCount( ) { return this->sessioncount; }
+ sess *createSession( );
+ void destroySession( string s_id );
+
+
+};
+
+
+#endif
+
diff --git a/ychat-0.4/sock.cpp b/ychat-0.4/sock.cpp
new file mode 100755
index 0000000..19c9510
--- /dev/null
+++ b/ychat-0.4/sock.cpp
@@ -0,0 +1,235 @@
+// 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( "" );
+
+ pthread_mutex_lock ( &(p_user->mut_message) );
+
+ do
+ {
+ s_msg = p_user->get_mess( );
+ if ( 0 > send( i_sock, s_msg.c_str(), s_msg.size(), 0 ) )
+ p_user->set_online( false );
+ pthread_cond_wait( &(p_user->cond_message), &(p_user->mut_message) );
+ }
+ while( p_user->get_online() );
+
+ // if there is still a message to send:
+ s_msg = p_user->get_mess( );
+ if ( ! s_msg.empty() )
+ send( i_sock, s_msg.c_str(), s_msg.size(), 0 );
+
+ pthread_mutex_unlock( &(p_user->mut_message) );
+
+ // remove the user from its room.
+ string s_user( p_user->get_name() );
+ p_user->get_p_room()->del_elem( s_user );
+
+ // post the room that the user has left the chat.
+ p_user->get_p_room()->msg_post( new string( p_user->get_name().append( s_lang::get().get_val( "USERLEAV" ) ) ) );
+ s_sman::get().destroySession( p_user->get_id() );
+ #ifdef VERBOSE
+ cout << s_user << " left | SessionCount: " << s_sman::get().getSessionCount() << endl;
+ #endif
+
+ p_user->~user();
+}
+
+int
+sock::make_socket( uint16_t i_port )
+{
+ int sock;
+ struct sockaddr_in name;
+
+ // create the server socket.
+ sock = socket (PF_INET, SOCK_STREAM, 0);
+ if (sock < 0)
+ {
+ cerr << "Sock: socket error" << endl;
+
+ if ( ++i_port > MAXPORT )
+ exit(-1);
+
+ cerr << SOCKERR << i_port << endl;
+ return make_socket( i_port );
+ }
+
+ // give the server socket a name.
+ name.sin_family = AF_INET;
+ name.sin_port = htons (i_port);
+ name.sin_addr.s_addr = htonl (INADDR_ANY);
+ int optval=1;
+
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof(int));
+
+ if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
+ {
+ cerr << "Sock: bind error" << endl;
+
+ if ( ++i_port > MAXPORT )
+ exit(-1);
+
+ cout << SOCKERR << i_port << endl;
+ return make_socket( i_port );
+ }
+
+ return sock;
+}
+
+int
+sock::read_write( thrd* p_thrd, int i_sock )
+{
+ char c_req[2048];
+
+ int i_bytes;
+ i_bytes = read (i_sock, c_req, 2048);
+
+ if (i_bytes < 0)
+ {
+ cerr << "Sock: read error " << endl;
+ }
+
+ else
+ {
+ // stores the request params.
+ map_string map_params;
+
+ // get the s_rep ( s_html response which will be send imediatly to the client
+ // and fill map_params with request values.
+ auto string s_temp=(string)c_req;
+ struct sockaddr_in client;
+ size_t size=sizeof(client);
+
+ getpeername( i_sock, (struct sockaddr *)&client, &size);
+
+ map_params["REMOTE_ADDR"]=inet_ntoa(client.sin_addr);
+ map_params["REMOTE_PORT"]=ntohs( client.sin_port);
+
+
+ string s_rep = req_parser->parse( p_thrd, string( c_req ), map_params );
+ // send s_rep to the client.
+ log_daemon->log(map_params);
+
+ send( i_sock, s_rep.c_str(), s_rep.size(), 0 );
+
+ // dont need those vals anymore.
+ map_params.clear();
+
+ return 0;
+ }
+
+ return -1;
+}
+
+int
+sock::start()
+{
+ auto int i_port = s_tool::string2int( s_conf::get().get_val( "SRVRPORT" ) );
+
+ int sock;
+ fd_set active_fd_set, read_fd_set;
+ int i;
+ struct sockaddr_in clientname;
+ size_t size;
+
+#ifdef VERBOSE
+ cout << SOCKCRT << "localhost:" << i_port << endl;
+#endif
+
+ // create the server socket and set it up to accept connections.
+ sock = make_socket ( i_port );
+
+ if (listen (sock, 1) < 0)
+ {
+ cerr << "Sock: listen error" << endl;
+ exit( EXIT_FAILURE );
+ }
+
+#ifdef VERBOSE
+ cout << SOCKRDY << endl;
+#endif
+
+ // initialize the set of active sockets.
+ FD_ZERO (&active_fd_set);
+ FD_SET (sock, &active_fd_set);
+
+ while( b_run )
+ {
+ // block until input arrives on one or more active sockets.
+ read_fd_set = active_fd_set;
+ if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
+ {
+ cerr << "Sock: select error" << endl;
+ exit( EXIT_FAILURE );
+ }
+
+ // service all the sockets with input pending.
+ for ( i = 0; i < FD_SETSIZE; i++ )
+ if ( FD_ISSET (i, &read_fd_set) )
+ {
+ if ( i == sock )
+ {
+ // connection request on original socket.
+ i_req++;
+ int new_sock;
+ size = sizeof (clientname);
+ new_sock = accept (sock,
+ (struct sockaddr *) &clientname,
+ &size);
+
+ if (new_sock < 0)
+ {
+ cerr << "Sock: accept error" << endl;
+ close ( new_sock );
+ }
+
+#ifdef VERBOSE
+ cout << CONNECT << i_req << " "
+ << inet_ntoa( clientname.sin_addr )
+ << ":"
+ << ntohs ( clientname.sin_port )
+ << endl;
+#endif
+
+ FD_SET (new_sock, &active_fd_set);
+ }
+
+ else
+ {
+ thrd_pool->run( (void*) new thrd( i ) );
+ FD_CLR( i, &active_fd_set );
+ }
+ }
+ }
+}
+
+#endif
diff --git a/ychat-0.4/sock.h b/ychat-0.4/sock.h
new file mode 100755
index 0000000..ea695c4
--- /dev/null
+++ b/ychat-0.4/sock.h
@@ -0,0 +1,53 @@
+// class sock declaration.
+
+#ifndef s_sock_H
+#define s_sock_H
+
+#include <queue>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include "incl.h"
+#include "pool.h"
+#include "reqp.h"
+#include "thrd.h"
+#include "user.h"
+#include "logd.h"
+using namespace std;
+
+class sock
+{
+private:
+ // total number of server requests.
+ unsigned long long int i_req;
+
+ bool b_run; // true while socket manager is running.
+ reqp* req_parser; // parses the http requests from clients.
+ pool* thrd_pool; // the thread pool.
+ logd* log_daemon; // the log daemon
+ // creates a server socket.
+ virtual int make_socket( uint16_t port );
+
+public:
+ // small inline methods:
+ bool get_run() const { return b_run; }
+ bool set_run( bool b_run ) { this->b_run = b_run; }
+
+ // public methods.
+ explicit sock( ); // simple constructor.
+ virtual int read_write( thrd* p_thrd, int filedes );
+ virtual int start();
+
+ // the chat stream there all the chat messages will sent through.
+ static void chat_stream( int i_sock, user* p_user, map_string &map_params );
+
+};
+
+#endif
diff --git a/ychat-0.4/thrd.cpp b/ychat-0.4/thrd.cpp
new file mode 100755
index 0000000..4bac39e
--- /dev/null
+++ b/ychat-0.4/thrd.cpp
@@ -0,0 +1,28 @@
+// class thrd implementation.
+
+#ifndef THRD_CXX
+#define THRD_CXX
+
+#include "thrd.h"
+#include "s_sock.h"
+
+using namespace std;
+
+thrd::thrd( int i_sock )
+{
+ this->i_sock = i_sock;
+}
+
+thrd::~thrd()
+{
+ shutdown ( get_sock() , 2 );
+ close ( get_sock() );
+}
+
+void
+thrd::run()
+{
+ s_sock::get().read_write( this, i_sock );
+}
+
+#endif
diff --git a/ychat-0.4/thrd.h b/ychat-0.4/thrd.h
new file mode 100755
index 0000000..fecdb49
--- /dev/null
+++ b/ychat-0.4/thrd.h
@@ -0,0 +1,26 @@
+// class thrd declaration.
+
+#ifndef THRD_H
+#define THRD_H
+
+#include "incl.h"
+
+using namespace std;
+
+class thrd
+{
+private:
+ int i_sock;
+
+public:
+
+ // small inline methods:
+ int get_sock() { return i_sock; }
+
+ // public methods:
+ explicit thrd( int i_sock );
+ ~thrd(); // destructor.
+ virtual void run();
+};
+
+#endif
diff --git a/ychat-0.4/todo.txt b/ychat-0.4/todo.txt
new file mode 100755
index 0000000..7e43eb2
--- /dev/null
+++ b/ychat-0.4/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/ychat-0.4/user.cpp b/ychat-0.4/user.cpp
new file mode 100755
index 0000000..4cda685
--- /dev/null
+++ b/ychat-0.4/user.cpp
@@ -0,0 +1,170 @@
+// class user implementation.
+
+#ifndef USER_CXX
+#define USER_CXX
+
+#include "user.h"
+#include "s_conf.h"
+#include "s_modl.h"
+#include "s_tool.h"
+
+using namespace std;
+
+user::user( string s_name ) : name( s_name )
+{
+ this -> b_online = true;
+ this -> l_time = s_tool::unixtime();
+ this -> s_col1 = s_conf::get().get_val( "USERCOL1" );
+
+ pthread_mutex_init( &mut_b_online, NULL);
+ pthread_mutex_init( &mut_i_sock , NULL);
+ pthread_mutex_init( &mut_l_time , NULL);
+ pthread_mutex_init( &mut_p_room , NULL);
+ pthread_mutex_init( &mut_s_mess , NULL);
+ pthread_cond_init ( &cond_message, NULL);
+ pthread_mutex_init( &mut_message , NULL);
+}
+
+user::~user()
+{
+ pthread_mutex_destroy( &mut_b_online );
+ pthread_mutex_destroy( &mut_i_sock );
+ pthread_mutex_destroy( &mut_l_time );
+ pthread_mutex_destroy( &mut_p_room );
+ pthread_mutex_destroy( &mut_s_mess );
+ pthread_cond_destroy ( &cond_message );
+ pthread_mutex_destroy( &mut_message );
+}
+
+void
+user::get_data( map_string *p_map_data )
+{
+ string s_req = (*p_map_data)["!get"];
+
+ // get the nick and the color of the user.
+ if ( s_req == "nick" )
+ (*p_map_data)[get_name()] = get_col1();
+}
+
+string
+user::get_mess( )
+{
+ string s_ret( "" );
+ pthread_mutex_lock ( &mut_s_mess );
+ s_ret.append( s_mess );
+ s_mess = *new string("");
+ pthread_mutex_unlock( &mut_s_mess );
+
+ return s_ret;
+}
+
+bool
+user::get_online( )
+{
+ bool b_ret;
+ pthread_mutex_lock ( &mut_b_online );
+ b_ret = b_online;
+ pthread_mutex_unlock( &mut_b_online );
+ return b_ret;
+}
+
+void
+user::set_online( bool b_online )
+{
+ pthread_mutex_lock ( &mut_b_online );
+ this -> b_online = b_online;
+ pthread_mutex_unlock( &mut_b_online );
+}
+
+room*
+user::get_p_room( )
+{
+ room* p_return;
+ pthread_mutex_lock ( &mut_p_room );
+ p_return = p_room;
+ pthread_mutex_unlock( &mut_p_room );
+ return p_return;
+}
+
+void
+user::set_p_room( room* p_room )
+{
+ pthread_mutex_lock ( &mut_p_room );
+ this -> p_room = p_room;
+ pthread_mutex_unlock( &mut_p_room );
+}
+
+int
+user::get_sock( )
+{
+ int i_ret;
+ pthread_mutex_lock ( &mut_i_sock );
+ i_ret = i_sock;
+ pthread_mutex_unlock( &mut_i_sock );
+ return i_ret;
+}
+
+void
+user::set_sock( int i_sock )
+{
+ pthread_mutex_lock ( &mut_i_sock );
+ this -> i_sock = i_sock;
+ pthread_mutex_unlock( &mut_i_sock );
+}
+
+void
+user::command( string &s_command )
+{
+
+ auto unsigned int pos = s_command.find( "/" );
+ while( pos != string::npos )
+ {
+ s_command.replace( pos, 1, "" );
+ pos = s_command.find( "/" );
+ }
+
+ string s_mod( "cmnd/yc_" );
+ s_mod.append( s_command ).append( ".so" );
+
+ dynmod *mod = s_modl::get().get_module( s_mod );
+
+ if ( mod == NULL )
+ {
+ msg_post( new string( s_lang::get().get_val( "ERRORCMD" ) ) );
+ return;
+ }
+
+ // execute the module.
+ ( *(mod->the_func) ) ( (void*) this );
+}
+
+void
+user::renew_stamp( )
+{
+ pthread_mutex_lock ( &mut_l_time );
+ l_time = s_tool::unixtime();
+ pthread_mutex_unlock( &mut_l_time );
+}
+
+void
+user::msg_post( string *p_msg )
+{
+ pthread_mutex_lock ( &mut_s_mess );
+ s_mess.append( *p_msg );
+ pthread_mutex_unlock( &mut_s_mess );
+
+ pthread_cond_signal( &cond_message );
+}
+
+void
+user::get_user_list( string &s_list, string &s_seperator )
+{
+ s_list.append( "<font color=\"" )
+ .append( get_col1() )
+ .append( "\">" )
+ .append( get_name() )
+ .append( "</font>\n" )
+ .append( s_seperator );
+
+}
+#endif
diff --git a/ychat-0.4/user.h b/ychat-0.4/user.h
new file mode 100755
index 0000000..75be662
--- /dev/null
+++ b/ychat-0.4/user.h
@@ -0,0 +1,84 @@
+// class user declaration.
+#ifndef USER_H
+#define USER_H
+
+#include "incl.h"
+#include "hmap.h"
+#include "name.h"
+#include "s_lang.h"
+using namespace std;
+
+class room;
+
+class user : public name
+{
+private:
+ // private members:
+ bool b_away; // true if user is away.
+ bool b_online; // true if user is online.
+ int i_sock; // user's stream socket descriptor.
+ long l_time; // user's last activity time.
+ rang r_rang; // user's rang ( see enum rang @ globals.h ).
+ rang r_oldr; // user's previous rang.
+ string s_id;
+ string s_agnt; // user's http user agent.
+ string s_away; // user's last away message.
+ string s_col1; // user's nick color.
+ string s_mess; // message string which has to be sent to the user.
+ room* p_room; // pointer to the user's room.
+
+ pthread_mutex_t mut_b_online;
+ pthread_mutex_t mut_i_sock;
+ pthread_mutex_t mut_l_time;
+ pthread_mutex_t mut_s_mess;
+ pthread_mutex_t mut_p_room;
+
+public:
+ pthread_cond_t cond_message;
+ pthread_mutex_t mut_message;
+
+ // small inline methods:
+ string get_col1() const { return s_col1; }
+ string get_id() const { return s_id; }
+ void set_id ( string s_id ) { this -> s_id = s_id; }
+ void set_col1 ( string s_col1 ) { this -> s_col1 = s_col1; }
+
+ rang get_rang ( ) const { return r_rang; }
+ void set_rang ( rang r_rang ) { r_oldr = this -> r_rang;
+ this -> r_rang = r_rang; }
+
+ bool new_msgs ( ) { return s_mess.empty(); }
+ // public methods:
+ explicit user( string s_name ); // a standard constructor.
+ ~user(); // user destructor.
+
+ // gets specific data of this user und stores it in
+ // (*p_map_string)["nick"]. this method will be used
+ // every time data has to be got from every user of a room
+ // or even of the system.
+ virtual void get_data( map_string *p_map_data );
+
+ virtual bool get_online();
+ virtual void set_online( bool b_online );
+ virtual room* get_p_room();
+ virtual void set_p_room( room* p_room );
+ virtual int get_sock ( );
+ virtual void set_sock ( int i_sock );
+
+ // executes a command.
+ virtual void command( string &s_command );
+
+ // gets the message and clears s_mess;
+ virtual string get_mess();
+
+ // actualizes the user's timestamp.
+ virtual void renew_stamp();
+
+ // Here are starting methods which are mainly needed by the data<type> class.
+
+ // appends a string to s_mess including br.
+ virtual void msg_post( string *p_msg );
+ virtual void get_user_list( string &s_list, string &s_seperator );
+};
+
+#endif