Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Directory moving

  • Loading branch information...
commit 903d70334de8debf139ffbc0db634362652c4a3c 0 parents
@paraboul paraboul authored
Showing with 6,174 additions and 0 deletions.
  1. +4 −0 AUTHORS
  2. +340 −0 LICENSE
  3. +26 −0 Makefile
  4. +10 −0 README
  5. +13 −0 bin/ace.conf
  6. +1 −0  bin/helloworld.conf
  7. +7 −0 bin/mod_mysql.conf
  8. +21 −0 bin/scripts/mod_helloworld.php
  9. +1 −0  doc/RFC
  10. +18 −0 modules/Makefile
  11. +22 −0 modules/global_plugins.h
  12. +129 −0 modules/libape-chat.c
  13. +75 −0 modules/libape-helloworld.c
  14. +112 −0 modules/libape-mysql.c
  15. +9 −0 modules/libape-mysql.h
  16. +242 −0 modules/libape-php.c
  17. +65 −0 modules/libape-setcord.c
  18. +70 −0 modules/plugins.h
  19. +65 −0 src/bots.c
  20. +32 −0 src/bots.h
  21. +554 −0 src/channel.c
  22. +82 −0 src/channel.h
  23. +96 −0 src/config.c
  24. +40 −0 src/config.h
  25. +188 −0 src/entry.c
  26. +112 −0 src/extend.c
  27. +42 −0 src/extend.h
  28. +217 −0 src/handle_http.c
  29. +56 −0 src/handle_http.h
  30. +165 −0 src/hash.c
  31. +40 −0 src/hash.h
  32. +145 −0 src/http.c
  33. +67 −0 src/http.h
  34. +250 −0 src/json.c
  35. +60 −0 src/json.h
  36. +129 −0 src/main.h
  37. +159 −0 src/plugins.c
  38. +88 −0 src/plugins.h
  39. +528 −0 src/raw.c
  40. +112 −0 src/raw.h
  41. +330 −0 src/sock.c
  42. +42 −0 src/sock.h
  43. +96 −0 src/ticks.c
  44. +52 −0 src/ticks.h
  45. +843 −0 src/users.c
  46. +253 −0 src/users.h
  47. +129 −0 src/utils.c
  48. +37 −0 src/utils.h
4 AUTHORS
@@ -0,0 +1,4 @@
+http://www.ape-project.org
+
+Weelya <contact@weelya.com> <http://www.weelya.net>
+Anthony Catel <a.catel@weelya.com>
340 LICENSE
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 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
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
26 Makefile
@@ -0,0 +1,26 @@
+EXEC=bin/aced
+
+prefix = /usr/local
+bindir = $(prefix)/bin
+
+
+SRC=src/entry.c src/sock.c src/hash.c src/handle_http.c src/raw.c src/users.c src/channel.c src/config.c src/json.c src/bots.c src/plugins.c src/http.c src/extend.c src/utils.c src/ticks.c
+
+CFLAGS=-Wall -g -minline-all-stringops -rdynamic
+LFLAGS=-ldl
+CC=gcc
+RM=rm -f
+
+all: aced
+
+aced: $(SRC)
+ $(CC) $(CFLAGS) $(SRC) -o $(EXEC) $(LFLAGS)
+install:
+ install -d $(bindir)
+ install -m 755 $(EXEC) $(bindir)
+
+uninstall:
+ $(RM) $(bindir)/aced
+
+clean:
+ $(RM) $(EXEC)
10 README
@@ -0,0 +1,10 @@
+To compile APE you need :
+- GCC
+- libc6-dev
+- 5 second'
+
+# make
+# cd modules/
+# make
+# cd ../bin/
+# ./aced
13 bin/ace.conf
@@ -0,0 +1,13 @@
+# APE Server Configuration file
+
+# listen porn
+port=6969
+####################
+# Not used for the moment
+connectedfile=connected
+####################
+# Launch APE as daemon [no/yes]
+daemon=no
+####################
+# Script domain name [See documentation]
+domain=ape-project.org
1  bin/helloworld.conf
@@ -0,0 +1 @@
+foo = Rulez the world
7 bin/mod_mysql.conf
@@ -0,0 +1,7 @@
+# Configuration for libape-mysql.c
+
+db_server = localhost
+db_name = APE
+db_user = root
+db_password = xxxx
+
21 bin/scripts/mod_helloworld.php
@@ -0,0 +1,21 @@
+<?php
+/* define('_MODULE_NAME_', 'Helloworld PHP Script');
+
+ echo 'Loading Module' . "\n";
+
+ function init_module()
+ {
+ echo 'bla' . "\n";
+ }
+
+*/
+ class ape_helloworld
+ {
+ public function __construct()
+ {
+ echo 'Anthony Catel is a god' . "\n";
+ return 'aaa';
+ }
+
+ }
+?>
1  doc/RFC
@@ -0,0 +1 @@
+See http://www.ape-project.org/
18 modules/Makefile
@@ -0,0 +1,18 @@
+CFLAGS=-Wall -g -shared -fPIC -rdynamic
+CC=gcc
+INCLUDE_PATH = -Iphp/ -Iphp/include -Iphp/main/ -Iphp/Zend -Iphp/TSRM
+PHP_LIB=php/libs/libphp5.a
+
+all: modules
+
+modules: libape-chat.c libape-mysql.c libape-setcord.c libape-helloworld.c libape-php.c
+ $(CC) $(CFLAGS) -Wl,-soname,libmod_mysql.so -L/usr/local/mysql/lib -lmysqlclient -lz -o lib/libmod_mysql.so libape-mysql.c
+ $(CC) $(CFLAGS) -Wl,-soname,libmod_setcord.so -o lib/libmod_setcord.so libape-setcord.c
+ $(CC) $(CFLAGS) -Wl,-soname,libmod_chat.so -o lib/libmod_chat.so libape-chat.c -L./lib -lmod_mysql -Xlinker "-R\$$ORIGIN"
+ #$(CC) $(CFLAGS) -Wl,-soname,libmod_helloworld.so -o lib/libmod_helloworld.so libape-helloworld.c
+ $(CC) -Wall -o ./objs/libape-php.o -c libape-php.c $(INCLUDE_PATH)
+ $(CC) $(CFLAGS) -Wl,-soname,libmod_php.so -o lib/libmod_php.so objs/libape-php.o $(PHP_LIB) -ldl -lm -lcrypt -lresolv -lxml2
+
+#./configure --enable-embed=static --with-zlib --enable-ftp --enable-static=zlib --disable-simplexml --disable-xmlreader --disable-xmlwriter --disable-soap
+
+
22 modules/global_plugins.h
@@ -0,0 +1,22 @@
+/*
+ Copyright (C) 2006, 2007, 2008, 2009 Anthony Catel <a.catel@weelya.com>
+
+ This file is part of ACE Server.
+ ACE 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.
+
+ ACE 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 ACE ; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* global_plugins.h */
+
+
129 modules/libape-chat.c
@@ -0,0 +1,129 @@
+/*
+ Adding support of nickname
+ CONNECT raw is overrided with new param (nickname) GET /?IP&CONNECT&nickname&anticache HTTP/1.1
+ USER object has now a property identidied by "nickname"
+
+ TODO : Move topic system, level, ban, kick, etc..
+*/
+
+#include "plugins.h"
+#include "global_plugins.h"
+#include "libape-mysql.h"
+
+#define MODULE_NAME "chat"
+
+static void hash_user(USERS *user, char *nick, acetables *g_ape);
+static USERS *get_user_by_nickname(char *nick, acetables *g_ape);
+/* This declaration is mandatory */
+
+/* Donner un nom pour la resolution global */
+static ace_plugin_infos infos_module = {
+ "\"Chat\" system", // Module Name
+ "0.01", // Module Version
+ "Anthony Catel",// Module Author
+ NULL // config file (bin/)
+};
+
+static unsigned int chat_connect(callbackp *callbacki)
+{
+ USERS *nuser;
+ RAW *newraw;
+
+ struct json *jstr = NULL;
+
+ if (get_user_by_nickname(callbacki->param[1], callbacki->g_ape)) {
+ ENVOI(callbacki->fdclient, "NICK_USED");
+
+ return (FOR_NOTHING);
+ }
+
+ nuser = adduser(callbacki->fdclient, callbacki->host, callbacki->g_ape);
+
+ callbacki->call_user = nuser;
+
+ if (nuser == NULL) {
+ ENVOI(callbacki->fdclient, ERR_CONNECT);
+
+ return (FOR_NOTHING);
+ }
+
+ hash_user(nuser, callbacki->param[1], callbacki->g_ape);
+ add_property_str(&nuser->properties, "name", callbacki->param[1]);
+
+
+ set_json("sessid", nuser->sessid, &jstr);
+ set_json("user", NULL, &jstr);
+
+ json_attach(jstr, get_json_object_user(nuser), JSON_OBJECT);
+
+ newraw = forge_raw(RAW_LOGIN, jstr);
+
+ post_raw(newraw, nuser);
+
+ #if 0
+
+ name = ape_mysql_get("SELECT name FROM user WHERE id = 1", callbacki->g_ape);
+
+ printf("From char : %s\n", name);
+
+ free(name);
+ #endif
+
+ return (FOR_LOGIN | FOR_UPDATE_IP);
+
+}
+
+static void chat_deluser(USERS *user, acetables *g_ape)
+{
+ hashtbl_erase(get_property(g_ape->properties, "nicklist")->val, get_property(user->properties, "name")->val);
+ deluser(user, g_ape);
+}
+
+static void hash_user(USERS *user, char *nick, acetables *g_ape)
+{
+ // get_property(g_ape->properties, "nicklist")->val <= this return a hashtable identified by "nicklist"
+ hashtbl_append(get_property(g_ape->properties, "nicklist")->val, nick, user);
+}
+
+static USERS *get_user_by_nickname(char *nick, acetables *g_ape)
+{
+ return hashtbl_seek(get_property(g_ape->properties, "nicklist")->val, nick);
+
+}
+
+void change_nick(USERS *user, char *nick, acetables *g_ape)
+{
+ struct CHANLIST *clist = user->chan_foot;
+
+ hashtbl_erase(get_property(g_ape->properties, "nicklist")->val, get_property(user->properties, "name")->val);
+ hash_user(user, nick, g_ape);
+
+ add_property_str(&user->properties, "name", nick);
+
+ while (clist != NULL) {
+ //RAW *new_raw;
+
+ clist = clist->next;
+ }
+}
+
+static void init_module(acetables *g_ape) // Called when module is loaded
+{
+ // Adding hashtable identified by "nicklist" to g_ape properties
+ add_property(&g_ape->properties, "nicklist", hashtbl_init());
+
+ // Overriding connect raw
+ register_raw("CONNECT", 1, chat_connect, NEED_NOTHING, g_ape);
+}
+
+
+static ace_callbacks callbacks = {
+ NULL, /* Called when new user is added */
+ chat_deluser, /* Called when a user is disconnected */
+ NULL, /* Called when new chan is created */
+ NULL, /* Called when a user join a channel */
+ NULL /* Called when a user leave a channel */
+};
+
+APE_INIT_PLUGIN(MODULE_NAME, init_module, callbacks)
+
75 modules/libape-helloworld.c
@@ -0,0 +1,75 @@
+#include <stdio.h>
+
+#include "plugins.h"
+#include "global_plugins.h"
+
+#define MODULE_NAME "helloworld" // Unique identifier
+
+/* You must name this "infos_module" because of macro READ_CONF */
+static ace_plugin_infos infos_module = {
+ "HelloWorld", // Module Name
+ "0.01", // Module Version
+ "Anthony Catel", // Module Author
+ "helloworld.conf" // Config file (from ./bin/) (can be NULL)
+};
+
+
+
+
+static unsigned int raw_helloworld(callbackp *callbacki)
+{
+ /* Sending a simple raw "Monkey" with "Helloworld" value */
+ send_msg(callbacki->call_user, "Helloworld", "Monkey");
+
+ /* Most used return */
+ return (FOR_NOTHING);
+}
+
+static void init_module(acetables *g_ape) // Called when module is loaded (passed to APE_INIT_PLUGIN)
+{
+ /* Print "foo" key from helloworld.conf */
+ printf("Helloworld loaded ;-) [Conf foo : %s]\n", READ_CONF("foo"));
+
+ /* Adding a new raw GET /?q&HELLOWORLD&[SESSID]&[ANTICACHE] */
+ register_raw("HELLOWORLD", 1, raw_helloworld, NEED_SESSID, g_ape);
+}
+
+/* Passed to callbacks list */
+static USERS *helloworld_adduser(unsigned int fdclient, char *host, acetables *ace_tables)
+{
+ /* */
+ /* Everything put here will be executed BEFORE user is added */
+ /* */
+
+
+ /* Call parent function (can be another plugin callback) */
+ USERS *n = adduser(fdclient, host, ace_tables);
+
+
+ /* */
+ /* Everything put here will be executed AFTER user is added */
+ /* */
+
+ if (n == NULL) {
+ return NULL;
+ }
+ printf("[Helloworld !] => %s user added\n", n->pubid);
+
+ /* Parent result must be returned (or NULL) */
+ return n;
+}
+
+
+
+
+/* See plugins.h for prototype */
+static ace_callbacks callbacks = {
+ helloworld_adduser, /* Called when new user is added */
+ NULL, /* Called when a user is disconnected */
+ NULL, /* Called when new chan is created */
+ NULL, /* Called when a user join a channel */
+ NULL /* Called when a user leave a channel */
+};
+
+/* Registering module (arg1 : unique identifier, arg2 : init function, arg3 : Callbacks list) */
+APE_INIT_PLUGIN(MODULE_NAME, init_module, callbacks)
112 modules/libape-mysql.c
@@ -0,0 +1,112 @@
+#include "libape-mysql.h"
+
+#include "plugins.h"
+#include "global_plugins.h"
+
+#define MODULE_NAME "mysql"
+
+
+int ape_mysql_connect(acetables *g_ape);
+
+static ace_plugin_infos infos_module = {
+ "MySQL support",
+ "0.01",
+ "Anthony Catel",
+ "mod_mysql.conf"
+};
+
+static void init_module(acetables *g_ape)
+{
+ MYSQL *mysql = mysql_init(NULL);
+
+ add_property(&g_ape->properties, "mysql", mysql);
+
+ /* init the connection to MySQL */
+ if (!ape_mysql_connect(g_ape)) {
+ fprintf(stderr, "[Module] [ERR] Connexion SQL : %s\n", mysql_error(mysql));
+ exit(0);
+ }
+}
+
+MYSQL *mysql_instance(acetables *g_ape)
+{
+ return get_property(g_ape->properties, "mysql")->val;
+}
+
+
+int ape_mysql_connect(acetables *g_ape)
+{
+ MYSQL *mysql = mysql_instance(g_ape);
+
+ if (!mysql_real_connect(mysql, READ_CONF("db_server"), READ_CONF("db_user"), READ_CONF("db_password"), READ_CONF("db_name"), 0, NULL, 0)) { // Faire une function generique
+ return 0;
+ }
+ mysql->reconnect = 1;
+ return 1;
+}
+
+MYSQL *ape_mysql_query(const char *query, acetables *g_ape)
+{
+ MYSQL *mysql = mysql_instance(g_ape);
+
+ if (mysql_query(mysql, query)) {
+ fprintf(stderr, "[Module] [SQL-WARN] : %s\n", mysql_error(mysql));
+ return NULL;
+ }
+ return mysql;
+}
+
+MYSQL_RES *ape_mysql_select(const char *query, acetables *g_ape)
+{
+ // must be free'd
+ MYSQL_RES *res;
+ MYSQL *mysql = ape_mysql_query(query, g_ape);
+
+ if (mysql == NULL) {
+ return NULL;
+ }
+
+ res = mysql_store_result(mysql);
+ if (res != NULL && !mysql_num_rows(res)) {
+ mysql_free_result(res);
+ return NULL;
+ }
+ return res;
+}
+
+MYSQL_ROW ape_mysql_row(const char *query, MYSQL_RES **res, acetables *g_ape)
+{
+ *res = ape_mysql_select(query, g_ape);
+ if (*res == NULL) {
+ return NULL;
+ }
+
+ return mysql_fetch_row(*res);
+}
+
+char *ape_mysql_get(const char *query, acetables *g_ape)
+{
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ char *field;
+
+ row = ape_mysql_row(query, &res, g_ape);
+ if (row != NULL) {
+ field = xstrdup(row[0]);
+ mysql_free_result(res);
+
+ return field;
+ }
+ return NULL;
+}
+
+static ace_callbacks callbacks = {
+ NULL, /* Called when new user is added */
+ NULL, /* Called when a user is disconnected */
+ NULL, /* Called when new chan is created */
+ NULL, /* Called when a user join a channel */
+ NULL /* Called when a user leave a channel */
+};
+
+APE_INIT_PLUGIN(MODULE_NAME, init_module, callbacks)
+
9 modules/libape-mysql.h
@@ -0,0 +1,9 @@
+#include <mysql/mysql.h>
+#include "plugins.h"
+
+MYSQL *mysql_instance(acetables *g_ape);
+MYSQL *ape_mysql_query(const char *query, acetables *g_ape);
+MYSQL_RES *ape_mysql_select(const char *query, acetables *g_ape);
+MYSQL_ROW ape_mysql_row(const char *query, MYSQL_RES **res, acetables *g_ape);
+char *ape_mysql_get(const char *query, acetables *g_ape);
+
242 modules/libape-php.c
@@ -0,0 +1,242 @@
+#include <stdio.h>
+#include <glob.h>
+
+#include "plugins.h"
+#include "global_plugins.h"
+
+#include "php.h"
+#include "php_version.h"
+#include "php_globals.h"
+#include "php_variables.h"
+#include "zend_modules.h"
+
+#include "SAPI.h"
+
+#include "php.h"
+//#include "build-defs.h"
+#include "zend.h"
+#include "zend_extensions.h"
+#include "php_ini.h"
+#include "php_globals.h"
+#include "php_main.h"
+#include "fopen_wrappers.h"
+#include "ext/standard/php_standard.h"
+
+#define MODULE_NAME "PHP" // Unique identifier
+
+
+static int ape_cli_startup(sapi_module_struct *sapi_module) /* {{{ */
+{
+ if (php_module_startup(sapi_module, NULL, 0) == FAILURE) {
+ return FAILURE;
+ }
+ php_printf("[Module] [%s] PHP %s Starting up...\n", MODULE_NAME, PHP_VERSION);
+ return SUCCESS;
+}
+static int ape_cli_shutdown(sapi_module_struct *sapi_module) /* {{{ */
+{
+ return SUCCESS;
+}
+
+static int ape_cli_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
+{
+ return SAPI_HEADER_SENT_SUCCESSFULLY;
+}
+static int ape_cli_ub_write(const char *str, uint str_length TSRMLS_DC)
+{
+ printf("%s", str);
+
+ return str_length;
+}
+
+static sapi_module_struct ape_sapi_module =
+{
+ "APEHandler", /* name */
+ "APE PHP Handler", /* pretty name */
+
+
+ ape_cli_startup, /* startup */
+ ape_cli_shutdown, /* shutdown */
+
+ NULL, /* activate */
+ NULL, /* deactivate */
+
+ ape_cli_ub_write, /* unbuffered write */
+ NULL, /* flush */
+ NULL, /* get uid */
+ NULL, /* getenv */
+
+ NULL, /* error handler */
+
+ NULL, /* header handler */
+ ape_cli_send_headers, /* send headers handler */
+ NULL, /* send header handler */
+
+ NULL, /* read POST data */
+ NULL, /* read Cookies */
+ NULL,
+
+ NULL, /* register server variables */
+ NULL, /* Log message */
+
+ NULL, /* Block interruptions */
+ NULL, /* Unblock interruptions */
+
+ STANDARD_SAPI_MODULE_PROPERTIES
+};
+
+
+
+
+
+/* You must name this "infos_module" because of macro READ_CONF */
+static ace_plugin_infos infos_module = {
+ "PHP embed", // Module Name
+ "0.01", // Module Version
+ "Anthony Catel", // Module Author
+ NULL // Config file (from ./bin/) (can be NULL)
+};
+
+/* From facebook library */
+static int eval_string(const char *fmt, ...)
+{
+ char *data = NULL;
+ int status;
+ va_list ap;
+
+ va_start(ap, fmt);
+
+
+ zend_first_try {
+ vspprintf(&data, 0, fmt, ap);
+ status = zend_eval_string(data, NULL, "" TSRMLS_CC);
+ } zend_catch {
+ status = 0;
+ } zend_end_try();
+
+ if (data) {
+ efree(data);
+ }
+
+ va_end(ap);
+ return status;
+}
+static void ape_exec_script(char *file)
+{
+ zval *function_name, *rv;
+ char *fn = "init_module";
+ zend_file_handle file_handle;
+
+ SG(request_info).request_method = NULL;
+ SG(request_info).query_string = NULL;
+ SG(request_info).content_type = NULL;
+ SG(request_info).request_uri = file;
+ SG(request_info).path_translated = file;
+ SG(request_info).content_length = 0;
+ SG(sapi_headers).http_response_code = 200;
+
+ SG(server_context) = NULL;
+
+ if (php_request_startup(TSRMLS_C) == FAILURE) {
+ printf("Cannot execute PHP...\n");
+ return;
+ }
+ //CG(interactive) = 1;
+ file_handle.handle.fp=VCWD_FOPEN(file,"rb");
+ file_handle.filename=file;
+ file_handle.type = ZEND_HANDLE_FP;
+ file_handle.free_filename = 0;
+ file_handle.opened_path = NULL;
+ php_execute_script(&file_handle);
+ /* Tricks from facebook php embed library and Sara Golmon book */
+ //eval_string("include_once('%s');", file);
+
+ MAKE_STD_ZVAL(function_name);
+ MAKE_STD_ZVAL(rv);
+
+ ZVAL_STRING(function_name, fn, 0);
+
+ call_user_function(EG(function_table), NULL, function_name, rv, 0, NULL TSRMLS_CC);
+
+
+ //php_request_shutdown(NULL);
+}
+
+static void ape_init_class(char *classname)
+{
+ zval *function_name, *rv;
+
+ zend_class_entry **ce;
+ zval *dummy = NULL;
+
+ MAKE_STD_ZVAL(function_name);
+ ALLOC_ZVAL(rv);
+ Z_TYPE_P(rv) = IS_OBJECT;
+
+ ZVAL_STRING(function_name, "__construct", 0);
+
+ //if (zend_hash_find(EG(function_table), classname, strlen(classname)+1, (void**)&ce) == SUCCESS) {
+ if (zend_lookup_class(classname, strlen(classname), &ce TSRMLS_CC) == SUCCESS) {
+ object_init_ex(rv, *ce);
+ if (call_user_function_ex(&(*ce)->function_table, NULL, function_name, &dummy, 0, NULL, 0, NULL TSRMLS_CC) == SUCCESS) {
+
+ }
+ }
+}
+
+static void init_module(acetables *g_ape) // Called when module is loaded (passed to APE_INIT_PLUGIN)
+{
+ int i;
+ glob_t globbuf;
+
+ sapi_startup(&ape_sapi_module);
+ ape_sapi_module.startup(&ape_sapi_module);
+
+ glob("./scripts/*.php", 0, NULL, &globbuf);
+ for (i = 0; i < globbuf.gl_pathc; i++) {
+ ape_exec_script(globbuf.gl_pathv[i]);
+ ape_init_class("ape_helloworld");
+ }
+ globfree(&globbuf);
+}
+static USERS *ape_adduser(unsigned int fdclient, char *host, acetables *ace_tables)
+{
+ USERS *n;
+ zval *function_name, *rv, *method;
+
+ zend_class_entry *ce = ZEND_STANDARD_CLASS_DEF_PTR;
+
+ char *fn = "ape_helloworlds";
+ char *construct = "__construct";
+
+ MAKE_STD_ZVAL(function_name);
+ MAKE_STD_ZVAL(method);
+ ALLOC_INIT_ZVAL(rv);
+
+ ZVAL_STRING(function_name, fn, 0);
+ ZVAL_STRING(method, construct, 0);
+
+ object_init_ex(rv, ce);
+ if (zend_hash_find(EG(class_table), fn, strlen(fn)+1, (void**)&ce) == SUCCESS) {
+
+ object_init_ex(rv, ce);
+ }
+
+ //call_user_function_ex(CG(function_table), &function_name, NULL, &rv, 0, NULL, 0, NULL TSRMLS_CC);
+
+ n = adduser(fdclient, host, ace_tables);
+
+ return n;
+}
+
+/* See plugins.h for prototype */
+static ace_callbacks callbacks = {
+ ape_adduser, /* Called when new user is added */
+ NULL, /* Called when a user is disconnected */
+ NULL, /* Called when new chan is created */
+ NULL, /* Called when a user join a channel */
+ NULL /* Called when a user leave a channel */
+};
+
+/* Registering module (arg1 : unique identifier, arg2 : init function, arg3 : Callbacks list) */
+APE_INIT_PLUGIN(MODULE_NAME, init_module, callbacks)
65 modules/libape-setcord.c
@@ -0,0 +1,65 @@
+#include <stdio.h>
+
+
+#include "plugins.h"
+#include "global_plugins.h"
+
+#define MODULE_NAME "setcord"
+
+
+/* You must name this "infos_module" because of macro READ_CONF */
+static ace_plugin_infos infos_module = {
+ "Setcord", // Module Name
+ "0.02", // Module Version
+ "Anthony Catel", // Module Author
+ NULL // Config file
+};
+
+
+static unsigned int raw_setpos(callbackp *callbacki)
+{
+ /* ->param[1] is not used (sessid) */
+ int x = abs(atoi(callbacki->param[3])), y = abs(atoi(callbacki->param[4]));
+ char cx[8], cy[8];
+
+ if (x > 10000 || y > 10000) {
+ send_error(callbacki->call_user, "BAD_POS");
+ } else {
+
+ json *jlist;
+
+ /* Get channel structure by name */
+ if (get_pipe_strict(callbacki->param[2], callbacki->call_user, callbacki->g_ape) == NULL) {
+
+ send_error(callbacki->call_user, "UNKNOWN_PIPE");
+
+ /* Check if calling user is on this channel */
+ } else {
+ jlist = NULL;
+
+ /* Adding two persistant properties to calling user */
+ add_property_str(&callbacki->call_user->properties, "x", itos(x, cx));
+ add_property_str(&callbacki->call_user->properties, "y", itos(y, cy));
+
+ post_to_pipe(jlist, "POSITIONS", callbacki->param[2], getsubuser(callbacki->call_user, callbacki->host), NULL, callbacki->g_ape);
+ }
+ }
+ /* Nothing todo after */
+ return (FOR_NOTHING);
+}
+
+static void init_module(acetables *g_ape) // Called when module is loaded
+{
+ register_raw("SETPOS", 4, raw_setpos, NEED_SESSID, g_ape);
+}
+
+static ace_callbacks callbacks = {
+ NULL, /* Called when new user is added */
+ NULL, /* Called when a user is disconnected */
+ NULL, /* Called when new chan is created */
+ NULL, /* Called when a user join a channel */
+ NULL /* Called when a user leave a channel */
+};
+
+APE_INIT_PLUGIN(MODULE_NAME, init_module, callbacks)
+
70 modules/plugins.h
@@ -0,0 +1,70 @@
+/*
+ Copyright (C) 2006, 2007, 2008, 2009 Anthony Catel <a.catel@weelya.com>
+
+ This file is part of ACE Server.
+ ACE 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.
+
+ ACE 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 ACE ; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* ace.h */
+
+
+#ifndef _ACE
+#define _ACE
+
+#include "../src/main.h"
+#include "../src/channel.h"
+#include "../src/raw.h"
+#include "../src/extend.h"
+#include "../src/users.h"
+#include "../src/utils.h"
+#include "../src/plugins.h"
+#include "../src/ticks.h"
+
+#include <stdarg.h>
+
+#define READ_CONF(key) plugin_get_conf(infos_module.conf, key)
+
+typedef struct _ace_callbacks ace_callbacks;
+
+
+struct _ace_callbacks
+{
+ USERS *(*c_adduser)(unsigned int, char *, acetables *);
+ void (*c_deluser)(USERS *, acetables *);
+ CHANNEL *(*c_mkchan)(char *, char *, acetables *);
+ void (*c_join)(USERS *, CHANNEL *, acetables *);
+ void (*c_left)(USERS *, CHANNEL *, acetables *);
+ void (*c_post_raw)(RAW *, USERS *);
+};
+
+typedef struct _plug_config plug_config;
+struct _plug_config
+{
+ char *key;
+ char *value;
+ struct _plug_config *next;
+};
+
+#define APE_INIT_PLUGIN(modname, initfunc, modcallbacks) \
+ void ape_module_init(ace_plugins *module) \
+ { \
+ infos_module.conf = NULL; \
+ module->cb = &modcallbacks; \
+ module->infos = &infos_module; \
+ module->loader = initfunc; \
+ module->modulename = modname; \
+ }
+#endif
+
65 src/bots.c
@@ -0,0 +1,65 @@
+/*
+ Copyright (C) 2006, 2007, 2008, 2009 Anthony Catel <a.catel@weelya.com>
+
+ This file is part of ACE Server.
+ ACE 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.
+
+ ACE 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 ACE ; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* bots.c */
+
+#include "main.h"
+#include "channel.h"
+#include "users.h"
+#include "raw.h"
+#include "json.h"
+#include "plugins.h"
+// Please complete ;)
+
+#if 0
+USERS *bot_connect(char *nick, char *channel, acetables *ace_tables) // Verifier si deja connecté, que join
+{
+ USERS *nuser;
+ CHANNEL *jchan;
+
+ if ((nuser = seek_user_simple(nick, ace_tables))) { // No Ghost !!!
+ deluser(nuser, ace_tables);
+ }
+
+ nuser = adduser(nick, 0, "", ace_tables);
+ printf("Bot %s connected\n", nick);
+ if (channel != NULL) {
+
+ if ((jchan = getchan(channel, ace_tables)) == NULL) {
+
+ jchan = mkchan(channel, "Default%20Topic", ace_tables);
+
+ if (jchan == NULL) {
+
+ send_error(nuser, "CANT_JOIN_CHANNEL");
+
+ } else {
+
+ join(nuser, jchan, ace_tables);
+ }
+
+ } else {
+ join(nuser, jchan, ace_tables);
+ }
+ }
+
+ return nuser;
+}
+#endif
+
32 src/bots.h
@@ -0,0 +1,32 @@
+/*
+ Copyright (C) 2006, 2007, 2008, 2009 Anthony Catel <a.catel@weelya.com>
+
+ This file is part of ACE Server.
+ ACE 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.
+
+ ACE 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 ACE ; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* bots.h */
+
+#ifndef _BOTS
+#define _BOTS
+
+#include "main.h"
+#include "users.h"
+
+#if 0
+USERS *bot_connect(char *nick, char *channel, acetables *ace_tables);
+#endif
+
+#endif
554 src/channel.c
@@ -0,0 +1,554 @@
+/*
+ Copyright (C) 2006, 2007, 2008, 2009 Anthony Catel <a.catel@weelya.com>
+
+ This file is part of ACE Server.
+ ACE 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.
+
+ ACE 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 ACE ; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* channel.c */
+
+#include "main.h"
+#include "sock.h"
+#include "raw.h"
+#include "channel.h"
+#include "plugins.h"
+#include "handle_http.h"
+#include "utils.h"
+
+
+unsigned int isvalidchan(char *name)
+{
+ char *pName;
+ if (strlen(name) > MAX_CHAN_LEN) {
+ return 0;
+ }
+
+ for (pName = (*name == '*' ? &name[1] : name ); *pName; pName++) {
+ *pName = tolower(*pName);
+ if (!isalnum(*pName) || ispunct(*pName)) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+CHANNEL *mkchan(char *chan, char *topic, acetables *g_ape)
+{
+ CHANNEL *new_chan = NULL;
+ transpipe *tpipe;
+
+ FIRE_EVENT(mkchan, new_chan, chan, topic, g_ape);
+
+
+ if (!isvalidchan(chan)) {
+ return NULL;
+ }
+
+ new_chan = (CHANNEL *) xmalloc(sizeof(*new_chan));
+
+ memcpy(new_chan->name, chan, strlen(chan)+1);
+ //memcpy(new_chan->topic, DEFAULT_TOPIC, strlen(DEFAULT_TOPIC)+1);
+
+ new_chan->head = NULL;
+ new_chan->banned = NULL;
+ new_chan->properties = NULL;
+ gen_sessid_new(new_chan->pubid, g_ape);
+
+ new_chan->interactive = (*new_chan->name == '*' ? 0 : 1);
+
+ hashtbl_append(g_ape->hLusers, chan, (void *)new_chan);
+
+ memcpy(new_chan->topic, topic, strlen(topic)+1);
+
+ tpipe = init_pipe(new_chan, CHANNEL_PIPE);
+
+ hashtbl_append(g_ape->hPubid, new_chan->pubid, (void *)tpipe);
+
+ return new_chan;
+
+}
+
+CHANNEL *getchan(char *chan, acetables *g_ape)
+{
+ if (strlen(chan) > MAX_CHAN_LEN) {
+ return NULL;
+ }
+ return (CHANNEL *)hashtbl_seek(g_ape->hLusers, chan);
+}
+void rmchan(CHANNEL *chan, acetables *g_ape)
+{
+ transpipe *fpipe;
+
+ if (chan->head != NULL) {
+ return;
+ }
+ rmallban(chan);
+
+ fpipe = get_pipe(chan->pubid, g_ape);
+ hashtbl_erase(g_ape->hPubid, chan->pubid);
+ free(fpipe);
+
+ hashtbl_erase(g_ape->hLusers, chan->name);
+
+ clear_properties(&chan->properties);
+
+ free(chan);
+ chan = NULL;
+}
+void join(USERS *user, CHANNEL *chan, acetables *g_ape)
+{
+ userslist *list, *ulist;
+
+ CHANLIST *chanl;
+
+ FIRE_EVENT_NULL(join, user, chan, g_ape);
+
+ RAW *newraw;
+ json *jlist = NULL;
+ char level[8];
+
+ if (isonchannel(user, chan)) {
+ return;
+ }
+
+ list = (userslist *)xmalloc(sizeof(*list)); // is it free ?
+ list->userinfo = user;
+ list->level = 1;
+ list->next = chan->head;
+
+ chan->head = list;
+
+ chanl = (CHANLIST *)xmalloc(sizeof(*chanl)); // is it free ?
+ chanl->chaninfo = chan;
+ chanl->next = user->chan_foot;
+
+ user->chan_foot = chanl;
+
+
+ if (chan->interactive) {
+ jlist = NULL;
+
+ set_json("user", NULL, &jlist);
+ json_attach(jlist, get_json_object_user(user), JSON_OBJECT);
+
+ set_json("pipe", NULL, &jlist);
+ json_attach(jlist, get_json_object_channel(chan), JSON_OBJECT);
+
+ newraw = forge_raw(RAW_JOIN, jlist);
+ post_raw_channel_restricted(newraw, chan, user);
+
+ jlist = NULL;
+ set_json("users", NULL, &jlist);
+
+ ulist = chan->head;
+ while (ulist != NULL) {
+
+ struct json *juser = NULL;
+
+ if (ulist->userinfo != user) {
+ //make_link(user, ulist->userinfo);
+ }
+
+ sprintf(level, "%i", ulist->level);
+ set_json("level", level, &juser);
+
+ json_concat(juser, get_json_object_user(ulist->userinfo));
+
+ json_attach(jlist, juser, JSON_ARRAY);
+
+ ulist = ulist->next;
+ }
+ }
+
+
+ set_json("pipe", NULL, &jlist);
+ json_attach(jlist, get_json_object_channel(chan), JSON_OBJECT);
+
+ newraw = forge_raw(RAW_CHANNEL, jlist);
+ post_raw(newraw, user);
+
+ #if 0
+ if (user->flags & FLG_AUTOOP) {
+ setlevel(NULL, user, chan, 3);
+ }
+ #endif
+
+}
+
+void left_all(USERS *user, acetables *g_ape)
+{
+ CHANLIST *list, *tList;
+
+ if (user == NULL) {
+ return;
+ }
+
+ list = user->chan_foot;
+
+ while (list != NULL) {
+ tList = list->next;
+
+ left(user, list->chaninfo, g_ape);
+
+ list = tList;
+ }
+}
+
+void left(USERS *user, CHANNEL *chan, acetables *g_ape) // Vider la liste chainée de l'user
+{
+ userslist *list, *prev;
+
+ CHANLIST *clist, *ctmp;
+ RAW *newraw;
+ json *jlist;
+
+ FIRE_EVENT_NULL(left, user, chan, g_ape);
+
+ if (!isonchannel(user, chan)) {
+ return;
+ }
+ list = chan->head;
+ prev = NULL;
+
+ clist = user->chan_foot;
+ ctmp = NULL;
+
+ while (clist != NULL) {
+ if (clist->chaninfo == chan) {
+ if (ctmp != NULL) {
+ ctmp->next = clist->next;
+ } else {
+ user->chan_foot = clist->next;
+ }
+ free(clist);
+ clist = NULL;
+ break;
+ }
+ ctmp = clist;
+ clist = clist->next;
+ }
+
+
+ while (list != NULL && list->userinfo != NULL) {
+ if (list->userinfo == user) {
+ if (prev != NULL) {
+ prev->next = list->next;
+ } else {
+ chan->head = list->next;
+ }
+ free(list);
+ list = NULL;
+ if (chan->head != NULL && chan->interactive) {
+ jlist = NULL;
+
+ set_json("user", NULL, &jlist);
+ json_attach(jlist, get_json_object_user(user), JSON_OBJECT);
+
+
+ set_json("pipe", NULL, &jlist);
+ json_attach(jlist, get_json_object_channel(chan), JSON_OBJECT);
+
+ newraw = forge_raw(RAW_LEFT, jlist);
+ post_raw_channel(newraw, chan);
+ } else if (chan->head == NULL) {
+ rmchan(chan, g_ape); // A verifier
+ }
+ break;
+ }
+ prev = list;
+ list = list->next;
+ }
+
+}
+userslist *getlist(char *chan, acetables *g_ape)
+{
+ CHANNEL *lchan;
+
+ if (strlen(chan) > MAX_CHAN_LEN) {
+ return NULL;
+ }
+ if ((lchan = (CHANNEL *)hashtbl_seek(g_ape->hLusers, chan)) == NULL) {
+ return NULL;
+ }
+ return lchan->head;
+}
+
+/* get user info to a specific channel (i.e. level) */
+userslist *getuchan(USERS *user, CHANNEL *chan)
+{
+ userslist *list;
+
+ if (user == NULL || chan == NULL) {
+ return 0;
+ }
+ list = chan->head;
+
+ while (list != NULL) {
+ if (list->userinfo == user) {
+ return list;
+ }
+ list = list->next;
+ }
+ return NULL;
+}
+
+// TODO : Rewrite this f***g ugly function
+unsigned int setlevel(USERS *user_actif, USERS *user_passif, CHANNEL *chan, unsigned int lvl)
+{
+ RAW *newraw;
+ userslist *user_passif_chan, *user_actif_chan;
+ json *jlist;
+
+ char level[8];
+
+ user_passif_chan = getuchan(user_passif, chan);
+
+ if (user_actif != NULL) {
+ user_actif_chan = getuchan(user_actif, chan);
+
+ if (user_passif_chan == NULL || user_actif_chan == NULL || ((user_actif_chan->level < lvl || user_actif_chan->level < user_passif_chan->level) && !(user_actif->flags & FLG_AUTOOP)) || lvl < 1 || lvl > 32) {
+ send_error(user_actif, "SETLEVEL_ERROR");
+
+ return 0;
+ }
+
+ user_passif_chan->level = lvl;
+
+ if (chan->interactive) {
+ jlist = NULL;
+
+ set_json("ope", NULL, &jlist);
+ json_attach(jlist, get_json_object_user(user_passif), JSON_OBJECT);
+
+ set_json("opeur", NULL, &jlist);
+ json_attach(jlist, get_json_object_user(user_actif), JSON_OBJECT);
+
+ set_json("level", itos(lvl, level), &jlist);
+ set_json("channel", NULL, &jlist);
+ json_attach(jlist, get_json_object_channel(chan), JSON_OBJECT);
+
+ newraw = forge_raw(RAW_SETLEVEL, jlist);
+ post_raw_channel(newraw, chan);
+ }
+ return 1;
+ } else if (user_passif_chan != NULL && lvl > 0 && lvl < 32) {
+ user_passif_chan->level = lvl;
+
+ if (chan->interactive) {
+ jlist = NULL;
+
+ set_json("ope", NULL, &jlist);
+ json_attach(jlist, get_json_object_user(user_passif), JSON_OBJECT);
+
+ set_json("opeur", NULL, &jlist);
+ json_attach(jlist, get_json_object_user(NULL), JSON_OBJECT);
+
+ set_json("level", itos(lvl, level), &jlist);
+ set_json("channel", NULL, &jlist);
+ json_attach(jlist, get_json_object_channel(chan), JSON_OBJECT);
+
+ newraw = forge_raw(RAW_SETLEVEL, jlist);
+ post_raw_channel(newraw, chan);
+
+ }
+ return 1;
+ }
+ return 0;
+}
+unsigned int settopic(USERS *user, CHANNEL *chan, char *topic)
+{
+ RAW *newraw;
+ userslist *list;
+ json *jlist;
+
+ list = getuchan(user, chan);
+
+ if (list == NULL || list->level < 3 || strlen(topic)+1 > MAX_TOPIC_LEN) {
+
+ send_error(user, "SETTOPIC_ERROR");
+
+ } else {
+ memcpy(chan->topic, topic, strlen(topic)+1);
+
+ jlist = NULL;
+
+ set_json("user", NULL, &jlist);
+ json_attach(jlist, get_json_object_user(user), JSON_OBJECT);
+
+ set_json("channel", NULL, &jlist);
+ json_attach(jlist, get_json_object_channel(chan), JSON_OBJECT);
+
+ newraw = forge_raw(RAW_SETTOPIC, jlist);
+ post_raw_channel(newraw, chan);
+
+ return 1;
+ }
+ return 0;
+}
+
+void ban(CHANNEL *chan, USERS *banner, char *ip, char *reason, unsigned int expire, acetables *g_ape) // Ban IP
+{
+ userslist *uTmp, *tUtmp;
+ RAW *newraw;
+ json *jlist;
+ BANNED *blist, *bTmp;
+
+ unsigned int isban = 0;
+
+ long int nextime = (expire * 60)+time(NULL); // NOW !
+
+ if (chan == NULL) {
+ return;
+ }
+
+ uTmp = chan->head;
+ bTmp = chan->banned;
+
+ while (uTmp != NULL) {
+
+ if (strcmp(ip, uTmp->userinfo->ip) == 0) { // We find somebody with the same IP
+ jlist = NULL;
+
+ set_json("reason", reason, &jlist);
+ if (banner != NULL) {
+ set_json("banner", NULL, &jlist);
+ json_attach(jlist, get_json_object_user(banner), JSON_OBJECT);
+ } else {
+ set_json("banner", NULL, &jlist);
+ json_attach(jlist, get_json_object_user(NULL), JSON_OBJECT);
+ }
+ set_json("channel", NULL, &jlist);
+ json_attach(jlist, get_json_object_channel(chan), JSON_OBJECT);
+
+ newraw = forge_raw(RAW_BAN, jlist);
+
+ post_raw(newraw, uTmp->userinfo);
+
+ if (isban == 0) {
+ blist = xmalloc(sizeof(*blist));
+
+ strncpy(blist->ip, ip, 16);
+ strncpy(blist->reason, reason, 256);
+ blist->expire = nextime;
+ blist->next = bTmp;
+ chan->banned = blist;
+ isban = 1;
+ }
+ tUtmp = uTmp->next;
+ left(uTmp->userinfo, chan, g_ape); // if the user is the last : "chan" is free (rmchan())
+ uTmp = tUtmp;
+ continue;
+ }
+ uTmp = uTmp->next;
+ }
+
+}
+
+BANNED *getban(CHANNEL *chan, char *ip)
+{
+ BANNED *blist, *bTmp, *bWait;
+
+ blist = chan->banned;
+ bTmp = NULL;
+
+ while (blist != NULL) {
+ if (blist->expire < time(NULL)) {
+ bWait = blist->next;
+ free(blist);
+ blist = bWait;
+
+ if (bTmp == NULL) {
+ chan->banned = blist;
+ } else {
+ bTmp->next = blist;
+ }
+ continue;
+ } else if (strcmp(blist->ip, ip) == 0) {
+ return blist;
+ }
+ bTmp = blist;
+ blist = blist->next;
+ }
+
+ return NULL;
+}
+
+void rmban(CHANNEL *chan, char *ip)
+{
+ BANNED *blist, *bTmp, *bWait;
+
+ blist = chan->banned;
+ bTmp = NULL;
+
+ while (blist != NULL) {
+ if (blist->expire < time(NULL) || strcmp(blist->ip, ip) == 0) {
+ bWait = blist->next;
+ free(blist);
+ blist = bWait;
+
+ if (bTmp == NULL) {
+ chan->banned = blist;
+ } else {
+ bTmp->next = blist;
+ }
+ continue;
+ }
+
+ bTmp = blist;
+ blist = blist->next;
+ }
+}
+
+void rmallban(CHANNEL *chan)
+{
+ BANNED *blist, *bTmp;
+
+ blist = chan->banned;
+
+ while (blist != NULL) {
+ bTmp = blist->next;
+ free(blist);
+ blist = bTmp;
+ }
+ chan->banned = NULL;
+}
+
+struct json *get_json_object_channel(CHANNEL *chan)
+{
+ json *jstr = NULL;
+
+ //set_json("topic", chan->topic, &jstr);
+ //set_json("name", chan->name, &jstr); // See below
+ set_json("pubid", chan->pubid, &jstr);
+
+
+ //if (chan->properties != NULL) {
+ json *jprop = NULL;
+ set_json("properties", NULL, &jstr);
+
+ extend *eTmp = chan->properties;
+
+ while (eTmp != NULL) {
+ set_json(eTmp->key, eTmp->val, &jprop);
+ eTmp = eTmp->next;
+ }
+ /* a little hack to have the same behaviour than user */
+ set_json("name", chan->name, &jprop);
+ json_attach(jstr, jprop, JSON_OBJECT);
+ //}
+
+ return jstr;
+}
+
82 src/channel.h
@@ -0,0 +1,82 @@
+/*
+ Copyright (C) 2006, 2007, 2008 Anthony Catel <a.catel@weelya.com>
+
+ This file is part of ACE Server.
+ ACE 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.
+
+ ACE 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 ACE ; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* channel.h */
+
+#ifndef _CHANNEL
+#define _CHANNEL
+
+#include "main.h"
+
+
+#define MAX_TOPIC_LEN 128
+#define DEFAULT_TOPIC "Chat%20powered%20by%20AJAX%20Chat%20Engine\0"
+
+typedef struct CHANNEL
+{
+ char name[MAX_CHAN_LEN+1];
+ char topic[MAX_TOPIC_LEN+1];
+ char pubid[33];
+
+ struct userslist *head;
+
+ struct BANNED *banned;
+
+ struct _extend *properties;
+
+ int interactive;
+
+} CHANNEL;
+
+typedef struct BANNED
+{
+ char ip[16];
+ char reason[256];
+
+ long int expire;
+
+ struct BANNED *next;
+} BANNED;
+
+CHANNEL *mkchan(char *chan, char *topic, acetables *g_ape);
+CHANNEL *getchan(char *chan, acetables *g_ape);
+
+BANNED *getban(CHANNEL *chan, char *ip);
+
+int mkallchan(acetables *g_ape);
+
+void rmchan(CHANNEL *chan, acetables *g_ape);
+
+void join(struct USERS *user, CHANNEL *chan, acetables *g_ape);
+void left(struct USERS *user, CHANNEL *chan, acetables *g_ape);
+void left_all(struct USERS *user, acetables *g_ape);
+
+void ban(CHANNEL *chan, struct USERS *banner, char *ip, char *reason, unsigned int expire, acetables *g_ape);
+void rmban(CHANNEL *chan, char *ip);
+void rmallban(CHANNEL *chan);
+
+struct userslist *getlist(char *chan, acetables *g_ape);
+struct userslist *getuchan(struct USERS *user, CHANNEL *chan);
+
+unsigned int setlevel(struct USERS *user_actif, struct USERS *user_passif, CHANNEL *chan, unsigned int lvl);
+unsigned int settopic(struct USERS *user, CHANNEL *chan, char *topic);
+unsigned int isvalidchan(char *name);
+
+struct json *get_json_object_channel(CHANNEL *chan);
+#endif
96 src/config.c
@@ -0,0 +1,96 @@
+/*
+ Copyright (C) 2006, 2007, 2008 Anthony Catel <a.catel@weelya.com>
+
+ This file is part of ACE Server.
+ ACE 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.
+
+ ACE 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 ACE ; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* config.c */
+
+#include "main.h"
+#include "config.h"
+#include "utils.h"
+
+srvconfig *load_ace_config(const char *path_config)
+{
+ FILE *cfile;
+
+ char lines[MAX_IO+1], *tkn[32+1];
+
+ srvconfig *srv;
+ size_t nTok;
+
+ srv = (srvconfig *) xmalloc(sizeof(*srv));
+ printf("\nReading Config...");
+ if (NULL == (cfile = fopen(path_config, "r"))) {
+ printf("NO (unable to open %s)\n", path_config);
+ return NULL;
+ }
+ printf("YES\n");
+ srv->port = 0;
+ srv->max_connected = 0;
+
+ memset(srv->fConnected, '\0', sizeof(srv->fConnected));
+ memset(srv->daemon, '\0', sizeof(char));
+ memset(srv->domain, '\0', sizeof(char));
+
+
+ while(fgets(lines, MAX_IO, cfile)) {
+ if (*lines == '#' || *lines == '\n' || *lines == '\0') {
+ continue;
+ }
+ if (lines[strlen(lines)-1]=='\n' && removelast(lines, 1) == NULL) {
+ continue;
+ }
+ nTok = explode('=', lines, tkn, 16);
+ if (nTok == 1) {
+ if (strcmp(tkn[0], "port")==0) {
+ if (atoi(tkn[1]) < 1 || atoi(tkn[1]) > 65535) {
+ printf("Erreur: Port range <1-65535>\n");
+ return NULL;
+ }
+ srv->port = atoi(tkn[1]);
+ continue;
+ } else if (strcmp(tkn[0], "max_connected")==0) {
+ if (atoi(tkn[1]) < 0) {
+ srv->max_connected = 0;
+ continue;
+ }
+ srv->max_connected = atoi(tkn[1]);
+ continue;
+ } else if (strcmp(tkn[0], "connectedfile")==0) {
+ memcpy(srv->fConnected, tkn[1], strlen(tkn[1])+1);
+ continue;
+ } else if (strcmp(tkn[0], "daemon")==0) {
+ memcpy(srv->daemon, tkn[1], strlen(tkn[1])+1);
+ continue;
+ } else if (strcmp(tkn[0], "domain")==0) {
+ if (strlen(tkn[1])+1 < 512) {
+ memcpy(srv->domain, tkn[1], strlen(tkn[1])+1);
+ }
+ }
+ } else {
+ printf("Erreur: fichier de configuration non conforme\n");
+ return NULL;
+ }
+ }
+ if (
+ strlen(srv->daemon)==0 ||
+ srv->port==0) {
+ printf("Erreur: Fichier de configuration incomplet.\n");
+ return NULL;
+ }
+ return srv;
+}
40 src/config.h
@@ -0,0 +1,40 @@
+/*
+ Copyright (C) 2006, 2007, 2008 Anthony Catel <a.catel@weelya.com>
+
+ This file is part of ACE Server.
+ ACE 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.
+
+ ACE 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 ACE ; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* config.h */
+
+#ifndef _CONFIG
+#define _CONFIG
+
+#define ACE_CONFIG_FILE "ace.conf"
+
+typedef struct srvconfig {
+ unsigned int port;
+
+ unsigned int max_connected;
+
+
+ char daemon[32];
+
+ char fConnected[256];
+ char domain[512];
+
+} srvconfig;
+srvconfig *load_ace_config(const char *path_config);
+#endif
188 src/entry.c
@@ -0,0 +1,188 @@
+/*
+ Copyright (C) 2006, 2007, 2008, 2009 Anthony Catel <a.catel@weelya.com>
+
+ This file is part of ACE Server.
+ ACE 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.
+
+ ACE 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 ACE ; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* entry.c */
+
+#include "plugins.h"
+#include "main.h"
+#include "sock.h"
+
+#include "config.h"
+#include "raw.h"
+
+#include "channel.h"
+
+
+#include <signal.h>
+#include <syslog.h>
+#include <sys/resource.h>
+#include "utils.h"
+#include "ticks.h"
+
+#define _VERSION "0.8.0"
+
+#define _RLIMIT_ 50000
+
+static void signal_handler(int sign)
+{
+ printf("\nShutdown...!\n\n");
+ exit(1);
+}
+static void signal_pipe(int sign)
+{
+ return;
+}
+
+static void inc_rlimit()
+{
+ struct rlimit rl;
+
+ rl.rlim_cur = _RLIMIT_;
+ rl.rlim_max = _RLIMIT_;
+
+ setrlimit(RLIMIT_NOFILE, &rl);
+}
+
+int main(int argc, char **argv)
+{
+ srvconfig *srv;
+
+ int random;
+ unsigned int getrandom;
+
+
+ char cfgfile[512] = ACE_CONFIG_FILE;
+
+ register acetables *g_ape;
+
+ if (argc > 1 && strcmp(argv[1], "--version") == 0) {
+ printf("\n AJAX Push Engine Serveur %s - (C) Anthony Catel <a.catel@weelya.com>\n http://www.ape-project.org/\n\n", _VERSION);
+ return 0;
+ }
+ if (argc > 1 && strcmp(argv[1], "--help") == 0) {
+ printf("\n AJAX Push Engine Serveur %s - (C) Anthony Catel <a.catel@weelya.com>\n http://www.ape-project.org/\n", _VERSION);
+ printf("\n usage: aced [options]\n\n");
+ printf(" Options:\n --help : Display this help\n --version : Show version number\n --cfg <config path>: Load a specific config file (default is ace.conf)\n\n");
+ return 0;
+ } else if (argc > 2 && strcmp(argv[1], "--cfg") == 0) {
+ strncpy(cfgfile, argv[2], 512);
+ cfgfile[strlen(argv[2])] = '\0';
+
+ } else if (argc > 1) {
+ printf("\n AJAX Push Engine Serveur %s - (C) Anthony Catel <a.catel@weelya.com>\n http://www.ape-project.org/\n\n", _VERSION);
+ printf(" Unknown parameters - check \"aced --help\"\n\n");
+ return 0;
+ }
+ if (NULL == (srv = load_ace_config(cfgfile))) {
+ printf("\nExited...\n\n");
+ exit(1);
+ }
+ if (strcmp(srv->daemon, "yes") == 0) {
+ if (0 != fork()) {
+ exit(0);
+ }
+ if (-1 == setsid()) {
+ exit(0);
+ }
+ signal(SIGHUP, SIG_IGN);
+ if (0 != fork()) {
+ exit(0);
+ }
+ }
+ printf(" _ ___ ___ \n");
+ printf(" /_\\ | _ \\ __|\n");
+ printf(" / _ \\| _/ _| \n");
+ printf("/_/ \\_\\_| |___|\nAJAX Push Engine\n\n");
+
+ printf("Bind on port %i\n\n", srv->port);
+ printf("Version : %s\n", _VERSION);
+ printf("Build : %s %s\n", __DATE__, __TIME__);
+ printf("Author : Weelya (contact@weelya.com)\n\n");
+ if (strcmp(srv->daemon, "yes")==0) {
+ printf("Starting daemon.... pid : %i\n\n", getpid());
+ }
+ signal(SIGINT, &signal_handler);
+ signal(SIGPIPE, &signal_pipe);
+
+ if (getuid() == 0) {
+ inc_rlimit();
+ } else {
+ printf("[ERR] You must run APE as root\n");
+ return 0;
+ }
+
+ if (TICKS_RATE < 1) {
+ printf("[ERR] TICKS_RATE cant be less than 1\n");
+ return 0;
+ }
+
+ random = open("/dev/urandom", O_RDONLY);
+ if (!random) {
+ printf("Cannot open /dev/urandom... exiting\n");
+ return 0;
+ }
+ read(random, &getrandom, 3);
+ srand(getrandom);
+
+ g_ape = xmalloc(sizeof(*g_ape));
+
+ g_ape->hLogin = hashtbl_init();
+ g_ape->hSessid = hashtbl_init();
+
+ g_ape->hLusers = hashtbl_init();
+ g_ape->hPubid = hashtbl_init();
+
+
+ g_ape->srv = srv;
+
+
+ g_ape->hCallback = hashtbl_init();
+
+ g_ape->uHead = NULL;
+
+ g_ape->nConnected = 0;
+ g_ape->plugins = NULL;
+
+ g_ape->properties = NULL;
+
+ g_ape->timers = NULL;
+
+ add_periodical(0, 0, check_timeout, g_ape, g_ape);
+
+
+ do_register(g_ape);
+
+ findandloadplugin(g_ape);
+
+
+ sockroutine(g_ape->srv->port, g_ape);
+
+ hashtbl_free(g_ape->hLogin);
+ hashtbl_free(g_ape->hSessid);
+ hashtbl_free(g_ape->hLusers);
+
+ hashtbl_free(g_ape->hCallback);
+
+ free(g_ape->plugins);
+ free(srv);
+ free(g_ape);
+
+ return 0;
+}
+
112 src/extend.c
@@ -0,0 +1,112 @@
+/*
+ Copyright (C) 2006, 2007, 2008, 2009 Anthony Catel <a.catel@weelya.com>
+
+ This file is part of ACE Server.
+ ACE 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.
+
+ ACE 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 ACE ; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* extend.c */
+
+#include "extend.h"
+#include "main.h"
+#include "utils.h"
+
+extend *get_property(extend *current, char *key)
+{
+ while (current != NULL) {
+ if (strcmp(current->key, key) == 0) {
+ return current;
+ }
+ current = current->next;
+ }
+
+ return NULL;
+
+}
+void clear_properties(extend **entry)
+{
+ extend *pExtend = *entry, *pTmp;
+
+ while (pExtend != NULL) {
+ pTmp = pExtend->next;
+ if (pExtend->allocval == 1) {
+ free(pExtend->val);
+ }
+ free(pExtend);
+ pExtend = pTmp;
+ }
+ *entry = NULL;
+}
+extend *add_property_str(extend **entry, char *key, char *val)
+{
+ extend *new_property = NULL, *eTmp;
+
+ if (strlen(key) > 32) {
+ return NULL;
+ }
+ if ((eTmp = get_property(*entry, key)) != NULL) {
+ if (strlen(val) > strlen(eTmp->val)) {
+ eTmp->val = xrealloc(eTmp->val, sizeof(char) * (strlen(val)+1));
+ }
+
+ strcpy(eTmp->key, key);
+ strcpy(eTmp->val, val);
+
+ return eTmp;
+ }
+
+ eTmp = *entry;
+
+ new_property = xmalloc(sizeof(*new_property));
+ new_property->val = xmalloc(sizeof(char) * (strlen(val)+1));
+ new_property->allocval = 1;
+ strcpy(new_property->key, key);
+ strcpy(new_property->val, val);
+ new_property->next = eTmp;
+
+ *entry = new_property;
+
+ return new_property;
+
+}
+
+
+extend *add_property(extend **entry, char *key, void *val)
+{
+ extend *new_property = NULL, *eTmp;
+
+ if (strlen(key) > 32) {
+ return NULL;
+ }
+ if ((eTmp = get_property(*entry, key)) != NULL) {
+ return NULL;
+ }
+
+ eTmp = *entry;
+
+ new_property = xmalloc(sizeof(*new_property));
+
+ strcpy(new_property->key, key);
+ new_property->val = val;
+ new_property->allocval = 0;
+ new_property->next = eTmp;
+
+ *entry = new_property;
+
+ return new_property;
+
+}
+
+
42 src/extend.h
@@ -0,0 +1,42 @@
+/*
+ Copyright (C) 2006, 2007, 2008, 2009 Anthony Catel <a.catel@weelya.com>
+
+ This file is part of ACE Server.
+ ACE 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.
+
+ ACE 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 ACE ; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* extend.h */
+
+#ifndef _EXTEND
+#define _EXTEND
+
+
+typedef struct _extend extend;
+
+struct _extend
+{
+ char key[33];
+ void *val;
+
+ int allocval;
+
+ struct _extend *next;
+};
+
+extend *get_property(extend *current, char *key);
+void clear_properties(extend **entry);
+extend *add_property_str(extend **entry, char *key, char *val);
+extend *add_property(extend **entry, char *key, void *val);
+#endif
217 src/handle_http.c
@@ -0,0 +1,217 @@
+/*
+ Copyright (C) 2006, 2007, 2008, 2009 Anthony Catel <a.catel@weelya.com>
+
+ This file is part of ACE Server.
+ ACE 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.
+
+ ACE 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 ACE ; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* handle_http.c a renommer par core.c */
+
+
+#include "users.h"
+#include "handle_http.h"
+#include "raw.h"
+#include "utils.h"
+
+const char basic_chars[16] = { 'a', 'b', 'c', 'd', 'e', 'f', '0', '1',
+ '2', '3', '4', '5', '6', '7', '8', '9'
+ };
+
+
+void gen_sessid_new(char *input, acetables *g_ape)
+{
+ unsigned int i;
+
+ do {
+ for (i = 0; i < 32; i++) {
+ input[i] = basic_chars[rand()%16];
+ }
+ input[32] = '\0';
+ } while(seek_user_id(input, g_ape) != NULL || seek_user_simple(input, g_ape) != NULL); // Colision verification
+}
+
+
+
+static unsigned int fixpacket(char *pSock, int type)