From 9cd3ccffd5372dfde3af478e3f832f18db4be3f1 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sat, 6 Apr 2013 13:14:41 +0200 Subject: tagging tags --- ychat-0.4/COPYING | 339 +++++++++ ychat-0.4/CVS/Entries | 70 ++ ychat-0.4/CVS/Entries.Log | 4 + ychat-0.4/CVS/Repository | 1 + ychat-0.4/CVS/Root | 1 + ychat-0.4/Makefile.in | 12 + ychat-0.4/README | 179 +++++ ychat-0.4/base.cpp | 65 ++ ychat-0.4/base.h | 71 ++ ychat-0.4/chat.cpp | 147 ++++ ychat-0.4/chat.h | 46 ++ ychat-0.4/cmnd.cpp | 19 + ychat-0.4/cmnd.h | 18 + ychat-0.4/cmnd/CVS/Entries | 3 + ychat-0.4/cmnd/CVS/Repository | 1 + ychat-0.4/cmnd/CVS/Root | 1 + ychat-0.4/cmnd/yc_q.cpp | 21 + ychat-0.4/cmnd/yc_test.cpp | 12 + ychat-0.4/conf.cpp | 75 ++ ychat-0.4/conf.h | 24 + ychat-0.4/conf.txt | 72 ++ ychat-0.4/configure | 1555 +++++++++++++++++++++++++++++++++++++++++ ychat-0.4/configure.in | 28 + ychat-0.4/cont.cpp | 24 + ychat-0.4/cont.h | 26 + ychat-0.4/gfx/CVS/Entries | 3 + ychat-0.4/gfx/CVS/Repository | 1 + ychat-0.4/gfx/CVS/Root | 1 + ychat-0.4/gfx/y_ani_black.gif | Bin 0 -> 61100 bytes ychat-0.4/gfx/y_ani_white.gif | Bin 0 -> 53536 bytes ychat-0.4/glob.h | 63 ++ ychat-0.4/hmap.cpp | 180 +++++ ychat-0.4/hmap.h | 118 ++++ ychat-0.4/html.cpp | 140 ++++ ychat-0.4/html.h | 42 ++ ychat-0.4/html/CVS/Entries | 11 + ychat-0.4/html/CVS/Repository | 1 + ychat-0.4/html/CVS/Root | 1 + ychat-0.4/html/blank.html | 4 + ychat-0.4/html/frameset.html | 20 + ychat-0.4/html/index.html | 32 + ychat-0.4/html/input.html | 34 + ychat-0.4/html/notfound.html | 10 + ychat-0.4/html/online.html | 7 + ychat-0.4/html/stream.html | 30 + ychat-0.4/html/style.css | 11 + ychat-0.4/html/y_ani.gif | Bin 0 -> 35107 bytes ychat-0.4/html/y_black.gif | Bin 0 -> 61100 bytes ychat-0.4/incl.h | 16 + ychat-0.4/lang.cpp | 78 +++ ychat-0.4/lang.h | 24 + ychat-0.4/lang/CVS/Entries | 3 + ychat-0.4/lang/CVS/Repository | 1 + ychat-0.4/lang/CVS/Root | 1 + ychat-0.4/lang/de | 3 + ychat-0.4/lang/en | 3 + ychat-0.4/logd.cpp | 65 ++ ychat-0.4/logd.h | 24 + ychat-0.4/main.cpp | 98 +++ ychat-0.4/modl.cpp | 98 +++ ychat-0.4/modl.h | 29 + ychat-0.4/msgs.h | 36 + ychat-0.4/mutx.cpp | 20 + ychat-0.4/mutx.h | 21 + ychat-0.4/name.cpp | 32 + ychat-0.4/name.h | 28 + ychat-0.4/pool.cpp | 214 ++++++ ychat-0.4/pool.h | 77 ++ ychat-0.4/reqp.cpp | 281 ++++++++ ychat-0.4/reqp.h | 47 ++ ychat-0.4/room.cpp | 18 + ychat-0.4/room.h | 34 + ychat-0.4/s_chat.cpp | 10 + ychat-0.4/s_chat.h | 26 + ychat-0.4/s_conf.cpp | 10 + ychat-0.4/s_conf.h | 26 + ychat-0.4/s_html.cpp | 10 + ychat-0.4/s_html.h | 26 + ychat-0.4/s_lang.cpp | 10 + ychat-0.4/s_lang.h | 26 + ychat-0.4/s_modl.cpp | 10 + ychat-0.4/s_modl.h | 26 + ychat-0.4/s_mutx.cpp | 10 + ychat-0.4/s_mutx.h | 26 + ychat-0.4/s_sman.cpp | 10 + ychat-0.4/s_sman.h | 26 + ychat-0.4/s_sock.cpp | 10 + ychat-0.4/s_sock.h | 26 + ychat-0.4/s_tool.cpp | 111 +++ ychat-0.4/s_tool.h | 19 + ychat-0.4/sess.cpp | 35 + ychat-0.4/sess.h | 28 + ychat-0.4/sman.cpp | 48 ++ ychat-0.4/sman.h | 32 + ychat-0.4/sock.cpp | 235 +++++++ ychat-0.4/sock.h | 53 ++ ychat-0.4/thrd.cpp | 28 + ychat-0.4/thrd.h | 26 + ychat-0.4/todo.txt | 11 + ychat-0.4/user.cpp | 170 +++++ ychat-0.4/user.h | 84 +++ 101 files changed, 5942 insertions(+) create mode 100644 ychat-0.4/COPYING create mode 100644 ychat-0.4/CVS/Entries create mode 100644 ychat-0.4/CVS/Entries.Log create mode 100644 ychat-0.4/CVS/Repository create mode 100644 ychat-0.4/CVS/Root create mode 100755 ychat-0.4/Makefile.in create mode 100755 ychat-0.4/README create mode 100755 ychat-0.4/base.cpp create mode 100755 ychat-0.4/base.h create mode 100755 ychat-0.4/chat.cpp create mode 100755 ychat-0.4/chat.h create mode 100755 ychat-0.4/cmnd.cpp create mode 100755 ychat-0.4/cmnd.h create mode 100644 ychat-0.4/cmnd/CVS/Entries create mode 100644 ychat-0.4/cmnd/CVS/Repository create mode 100644 ychat-0.4/cmnd/CVS/Root create mode 100644 ychat-0.4/cmnd/yc_q.cpp create mode 100644 ychat-0.4/cmnd/yc_test.cpp create mode 100755 ychat-0.4/conf.cpp create mode 100755 ychat-0.4/conf.h create mode 100755 ychat-0.4/conf.txt create mode 100755 ychat-0.4/configure create mode 100644 ychat-0.4/configure.in create mode 100755 ychat-0.4/cont.cpp create mode 100755 ychat-0.4/cont.h create mode 100644 ychat-0.4/gfx/CVS/Entries create mode 100644 ychat-0.4/gfx/CVS/Repository create mode 100644 ychat-0.4/gfx/CVS/Root create mode 100755 ychat-0.4/gfx/y_ani_black.gif create mode 100755 ychat-0.4/gfx/y_ani_white.gif create mode 100755 ychat-0.4/glob.h create mode 100644 ychat-0.4/hmap.cpp create mode 100644 ychat-0.4/hmap.h create mode 100755 ychat-0.4/html.cpp create mode 100755 ychat-0.4/html.h create mode 100644 ychat-0.4/html/CVS/Entries create mode 100644 ychat-0.4/html/CVS/Repository create mode 100644 ychat-0.4/html/CVS/Root create mode 100755 ychat-0.4/html/blank.html create mode 100755 ychat-0.4/html/frameset.html create mode 100755 ychat-0.4/html/index.html create mode 100755 ychat-0.4/html/input.html create mode 100755 ychat-0.4/html/notfound.html create mode 100755 ychat-0.4/html/online.html create mode 100755 ychat-0.4/html/stream.html create mode 100644 ychat-0.4/html/style.css create mode 100755 ychat-0.4/html/y_ani.gif create mode 100755 ychat-0.4/html/y_black.gif create mode 100755 ychat-0.4/incl.h create mode 100755 ychat-0.4/lang.cpp create mode 100755 ychat-0.4/lang.h create mode 100644 ychat-0.4/lang/CVS/Entries create mode 100644 ychat-0.4/lang/CVS/Repository create mode 100644 ychat-0.4/lang/CVS/Root create mode 100644 ychat-0.4/lang/de create mode 100644 ychat-0.4/lang/en create mode 100644 ychat-0.4/logd.cpp create mode 100644 ychat-0.4/logd.h create mode 100755 ychat-0.4/main.cpp create mode 100755 ychat-0.4/modl.cpp create mode 100755 ychat-0.4/modl.h create mode 100755 ychat-0.4/msgs.h create mode 100755 ychat-0.4/mutx.cpp create mode 100755 ychat-0.4/mutx.h create mode 100755 ychat-0.4/name.cpp create mode 100755 ychat-0.4/name.h create mode 100755 ychat-0.4/pool.cpp create mode 100755 ychat-0.4/pool.h create mode 100755 ychat-0.4/reqp.cpp create mode 100755 ychat-0.4/reqp.h create mode 100755 ychat-0.4/room.cpp create mode 100755 ychat-0.4/room.h create mode 100644 ychat-0.4/s_chat.cpp create mode 100644 ychat-0.4/s_chat.h create mode 100644 ychat-0.4/s_conf.cpp create mode 100644 ychat-0.4/s_conf.h create mode 100644 ychat-0.4/s_html.cpp create mode 100644 ychat-0.4/s_html.h create mode 100644 ychat-0.4/s_lang.cpp create mode 100644 ychat-0.4/s_lang.h create mode 100644 ychat-0.4/s_modl.cpp create mode 100644 ychat-0.4/s_modl.h create mode 100644 ychat-0.4/s_mutx.cpp create mode 100644 ychat-0.4/s_mutx.h create mode 100644 ychat-0.4/s_sman.cpp create mode 100644 ychat-0.4/s_sman.h create mode 100644 ychat-0.4/s_sock.cpp create mode 100644 ychat-0.4/s_sock.h create mode 100644 ychat-0.4/s_tool.cpp create mode 100644 ychat-0.4/s_tool.h create mode 100644 ychat-0.4/sess.cpp create mode 100644 ychat-0.4/sess.h create mode 100644 ychat-0.4/sman.cpp create mode 100644 ychat-0.4/sman.h create mode 100755 ychat-0.4/sock.cpp create mode 100755 ychat-0.4/sock.h create mode 100755 ychat-0.4/thrd.cpp create mode 100755 ychat-0.4/thrd.h create mode 100755 ychat-0.4/todo.txt create mode 100755 ychat-0.4/user.cpp create mode 100755 ychat-0.4/user.h (limited to 'ychat-0.4') 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. + + + Copyright (C) 19yy + + 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. + + , 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 base + | | 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 +base::base() +{ + map_elem = new hmap(80); + pthread_mutex_init (&mut_map_elem, NULL ); +} + +template +base::~base( ) +{ + pthread_mutex_destroy( &mut_map_elem ); +} + +template void +base::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 void +base::del_elem( string &s_name ) +{ + pthread_mutex_lock ( &mut_map_elem ); + map_elem->del_elem ( s_name ); + pthread_mutex_unlock( &mut_map_elem ); +} + +template type* +base::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 void +base::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 base +{ +private: + hmap* 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::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::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 usernameseperator + 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::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*)¶m ); + + if ( *( (bool*)param.elem[1] ) ) + return (user*)param.elem[2]; +} + +void +chat::get_user_( room *room_obj, void *v_arg ) +{ + container* param = (container*) v_arg; + param->elem[2] = (void*)room_obj->get_elem( *((string*)param->elem[0]), *((bool*)param->elem[1]) ); +} + +void +chat::login( map_string &map_params ) +{ + string s_user = map_params["nick"]; + + // prove if nick is empty: + if ( s_user.empty() ) + { + map_params["INFO"] = E_NONICK; + map_params["request"] = s_conf::get().get_val( "STARTMPL" ); // redirect to the startpage. + return; + } + + // prove if the nick ist alphanumeric: + else if ( ! s_tool::is_alpha_numeric( s_user ) ) + { + map_params["INFO"] = E_ALPNUM; + map_params["request"] = s_conf::get().get_val( "STARTMPL" ); // redirect to the startpage. + return; + } + + bool b_flag; + + // prove if nick is already online / logged in. + get_user( s_user, b_flag ); + if ( b_flag ) + { + map_params["INFO"] = E_ONLINE; + map_params["request"] = s_conf::get().get_val( "STARTMPL" ); + return; + } + + string s_room = map_params["room"]; + room* p_room = get_room( s_room , b_flag ); + + // if room does not exist add room to list! + if ( ! b_flag ) + { + p_room = new room( s_room ); + +#ifdef VERBOSE + pthread_mutex_lock ( &s_mutx::get().mut_stdout ); + cout << NEWROOM << s_room << endl; + pthread_mutex_unlock( &s_mutx::get().mut_stdout ); +#endif + + add_elem( p_room ); + } + + user *p_user = new user( s_user ); + + // add user to the room. + p_room->add_user( p_user ); + sess *ns =s_sman::get().createSession(); + ns->setValue(string("nick"), (void *)new string(s_user) ); + map_params["tmpid"]=ns->getId(); + // post "username enters the chat" into the room. + p_room->msg_post( new string( s_user.append( s_lang::get().get_val( "USERENTR" ) ) ) ); + +#ifdef VERBOSE + pthread_mutex_lock ( &s_mutx::get().mut_stdout ); + cout << LOGINPR << s_user << endl; + pthread_mutex_unlock( &s_mutx::get().mut_stdout ); +#endif +} + +void +chat::post( user* p_user, map_string &map_params ) +{ + + string s_msg( map_params["message"] ); + + auto unsigned i_pos = s_msg.find( "/" ); + if ( i_pos == 0 ) + return p_user->command( s_msg ); + + if ( b_strip_html ) + s_tool::strip_html( &s_msg ); + + string s_post( "get_col1() ) + .append( "\">" ) + .append( p_user->get_name() ) + .append( ": " ) + .append( s_msg ) + .append( "
\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 +#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 +{ +private: + bool b_strip_html; + +public: + + + room* get_room( string &s_name, bool &b_found ) + { + return static_cast( 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 +#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( "\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 + +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 +#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 <&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 <&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 < +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 < +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 < +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 <&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 <&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 <&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 < +#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 <&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 <&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 <&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 < +#include +#include +#include +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 +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 +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 < +#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 +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 <&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 +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 <&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 <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 <&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 < 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 </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 < 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 <> $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 <> $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 Binary files /dev/null and b/ychat-0.4/gfx/y_ani_black.gif 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 Binary files /dev/null and b/ychat-0.4/gfx/y_ani_white.gif 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 +#include + +// 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 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 +hmap::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 +void hmap::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 +void hmap::rehash( ) +{ + vector 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 +unsigned int hmap::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 +int hmap::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 +void hmap::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 +obj_type hmap::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 +void hmap::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 +bool hmap::isActive( int currentPos ) const +{ + return array[ currentPos ].info == ACTIVE; +} + + +// Internal method to test if a positive number is prime. +// Not an efficient algorithm. +template +bool hmap::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 +int hmap::nextPrime( int n ) const +{ + if( n % 2 == 0 ) + n++; + + for( ; !isPrime( n ); n += 2 ); + + return n; +} +template void +hmap::run_func( void (*func)(obj_type) ) +{ + for( int i = 0; i < array.size( ); i++ ) + if ( array[i].info == ACTIVE ) + ( *func ) ( array[i].element ); +} + +template void +hmap::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 +#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 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 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(getSize())/static_cast(getCapacity()); + } + + obj_type& operator[]( key_type &k ) + { + return get_elem( k ); + } + +}; + +template +class linearhmap : public hmap { +public: + linearhmap(double moc) : hmap(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 +#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( "
" ); + + 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 @@ + + + + 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 @@ + + + + %%PGETITLE%% + + + + + Your browser does not support frames, + + + + + + + + + + + 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 @@ + + + + %%PGETITLE%% + + + + + + + + + + + + + + + +
ychat%%PGETITLE%%
%%INFO%%
 
+Enter your nick: +
+ + + + +
+
+

+
yChat is OpenSource - get it at http://www.yChat.org
+ + 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 @@ + + + + %%PGETITLE%% + + + + + + +
+ + + + + + +
+ + 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 @@ + + + + %%PGETITLE%% + + + + Page not found. + + 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 @@ + + + + + %%MESSAGE%% + + 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 @@ + + + + %%PGETITLE%% + + + + + + Welcome to yChat %%nick%%! +
+
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 Binary files /dev/null and b/ychat-0.4/html/y_ani.gif 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 Binary files /dev/null and b/ychat-0.4/html/y_black.gif 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 + +// since thread synchronization is a big issue this header needs +// to be included by every other file too. +#include + +// std::string. +#include + +// 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 +#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="Befehl nicht gefunden!
"; +USERENTR=" betritt den Chat.
"; +USERLEAV=" verläßt den Chat.
" 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=" No such command!
"; +USERENTR=" enters the chat
"; +USERLEAV=" leaves the chat
"; 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 +#include +#include +class logd { + + private: + string s_logfile; + queue 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 + +// 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 +#include +#include +#include + +#include "s_mutx.h" +#include "modl.h" + +using namespace std; + +modl::modl( ) +{ + map_mods = new hmap(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* 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.

" +#define E_NONICK "You need to specify a nick name.

" +#define E_NOTONL "An error occured. Your nick is not online.

" +#define E_ONLINE "The nick you have specified is already online. Try another nick.

" + +// 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(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 +#include "incl.h" +#include "thrd.h" + +using namespace std; + +typedef map > 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, 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( 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 +#include +#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= '0' && *digit <='9') { + result = (result * 10) + (*digit - '0'); + digit++; + } + + // Check that there were no non-digits at end. + if (*digit != 0) { + return -1; + } + + return result; +} + +long +s_tool::unixtime() +{ + return (long) time( NULL ); +} + + +void +s_tool::strip_html( string *s_str ) +{ + auto int i_pos; + + if((i_pos=s_str->find("<",0))==string::npos) + return; + while(true) + { + + s_str->replace(i_pos,1,"<"); + + if((i_pos=s_str->find("<",0))==string::npos) + return; + + } + + +} +#endif diff --git a/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::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 +#include +#include "hmap.h" +using namespace std; + +typedef map 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(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;igenerateId(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 + +using namespace std; + +class sman{ + + private: + hmap *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 + +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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( "" ) + .append( get_name() ) + .append( "\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 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 -- cgit v1.2.3