Initial import
This commit is contained in:
		
							
								
								
									
										5
									
								
								Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| ACLOCAL_AMFLAGS=-I m4 | ||||
| SUBDIRS = libwmud-session libwmud-world libwmud-state-sqlite3 libwmud-protocol-telnet src doc/reference/libwmud-session doc/reference/libwmud-world | ||||
| dist_doc_DATA = README | ||||
|  | ||||
| DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc --enable-debug | ||||
							
								
								
									
										11
									
								
								README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								README
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| What is wMUD? | ||||
| ============= | ||||
|   On one hand, wMUD is a new (well, yet another) MUD (Multi-User Dungeon) | ||||
| server. It is designed to run as smoothly as possible, which is achieved by | ||||
| using threads. During development I tried to eliminate everything which is not | ||||
| GLib, so, although not tested yet, it should by highly portable. | ||||
|  | ||||
|   On the other hand, wMUD is a learning project for GLib's several features. | ||||
| This means that although I double check every byte of code, it can still have | ||||
| bugs or not-so-effective code chunks. If you find one, please don't hesitate to | ||||
| contact me, or send a patch! | ||||
							
								
								
									
										76
									
								
								TODO
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								TODO
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| CLIENT FLOW | ||||
| =========== | ||||
|  | ||||
| [X] connection arrives | ||||
| [X] connection gets accept()'ed | ||||
| [ ] connection is closed if the IP is banned | ||||
| [X] session object created | ||||
| [ ] welcome banner gets sent | ||||
| [X] user sends commans | ||||
| [ ] commands get processed | ||||
| [X] user sends the QUIT command | ||||
| [X] session gets destroyed | ||||
| [X] connection gets destroyed | ||||
|  | ||||
|  | ||||
| TO-DO LIST | ||||
| ========== | ||||
|  | ||||
| [X] Create own text formatting style | ||||
|  | ||||
| [o] Create converter that can convert from own style to | ||||
|       [X] ANSI | ||||
|       [ ] colourless text | ||||
|       [ ] HTML | ||||
|       [ ] Pango markup | ||||
|       only the first two are very important | ||||
|  | ||||
| [X] Do basic jobs for later threading support | ||||
|  | ||||
| [X] Create and run the world object in a separate thread | ||||
|  | ||||
| [X] Implement session handling | ||||
|  | ||||
| [X] Create telnet interface that can process commands and send colourful | ||||
|       responses. This should go in a separate thread. | ||||
|  | ||||
| [X] Plan configurable parameters and configuration file format | ||||
|  | ||||
| [X] Write configuration reading code | ||||
|  | ||||
| [o] Create XML schemas for world description | ||||
|  | ||||
| [ ] Specify a way how new attribute and object types can be inserted into | ||||
|       a running system | ||||
|  | ||||
| [ ] Specify state-saving backends: | ||||
|       [ ] SQLite3 | ||||
|       [ ] MySQL | ||||
|       [ ] PostgreSQL | ||||
|       [ ] XML | ||||
|       [ ] GDBM | ||||
|  | ||||
| [ ] Specify data to be saved during state-save | ||||
|  | ||||
| [ ] Write state saving (command and timed hook) and loading (command and | ||||
|       startup time) code | ||||
|  | ||||
| [o] Write world description loading and reloading code | ||||
|  | ||||
| [ ] Write User Account management code (possibility of registration, | ||||
|       login, logout, account deletion, ban, kick and purge | ||||
|  | ||||
| [o] Write chat possibility | ||||
|  | ||||
| [ ] Write Light-calculation code | ||||
|  | ||||
| [ ] Plan initial character state (what attributes to use, look, cloths, | ||||
|       armour, weapon, etc.) | ||||
|  | ||||
| [ ] Create the possibility to enter the world | ||||
|  | ||||
| [ ] Create the possibility to move in the world | ||||
|  | ||||
| [ ] Create a DBus module to control the whole program | ||||
|  | ||||
| # vim: textwidth=78 : tabstop=8 : expandtab | ||||
							
								
								
									
										30
									
								
								configure.ac
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								configure.ac
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| AC_INIT([wmud], [1.0], [polesz@w00d5t0ck.info]) | ||||
| AM_INIT_AUTOMAKE([-Wall -Werror foreign]) | ||||
| LT_INIT | ||||
| AC_ARG_ENABLE(debug, [AC_HELP_STRING([--enable-debug], [compile with debugging support. Be warned that debugging support can eat a large amount of CPU when many clients are connected. Also, debug logs can become very large!])], , enable_debug=no) | ||||
|                 | ||||
| if test "x$enable_debug" = "xyes" ; then | ||||
| 	AC_DEFINE([DEBUG], [1], [Define if debugging is enabled.]) | ||||
| fi | ||||
|  | ||||
| AC_PROG_CC | ||||
| AC_PROG_LIBTOOL | ||||
| PKG_PROG_PKG_CONFIG | ||||
| PKG_CHECK_MODULES([GLIB], [glib-2.0]) | ||||
| PKG_CHECK_MODULES([GOBJECT], [gobject-2.0]) | ||||
| PKG_CHECK_MODULES([GNET], [gnet-2.0]) | ||||
| PKG_CHECK_MODULES([EXTLIBS], [libxml-2.0, glib-2.0, gobject-2.0, gthread-2.0, gnet-2.0, gnome-vfs-2.0, sqlite3 gmodule-2.0]) | ||||
| GTK_DOC_CHECK([1.10]) | ||||
| AC_CONFIG_MACRO_DIR([m4]) | ||||
| AC_CONFIG_HEADERS([config.h]) | ||||
| AC_CONFIG_FILES([ | ||||
| 	Makefile | ||||
| 	libwmud-session/Makefile | ||||
| 	libwmud-world/Makefile | ||||
| 	libwmud-state-sqlite3/Makefile | ||||
| 	libwmud-protocol-telnet/Makefile | ||||
| 	src/Makefile | ||||
| 	doc/reference/libwmud-session/Makefile | ||||
| 	doc/reference/libwmud-world/Makefile | ||||
| ]) | ||||
| AC_OUTPUT | ||||
							
								
								
									
										0
									
								
								data/state.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								data/state.sql
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										68
									
								
								data/wmud.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								data/wmud.conf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| # general options | ||||
| [general] | ||||
| # log can be "syslog" (to log through the syslog facility), "file:<filename>" | ||||
| # to log to the specified file, "console" (to log to the console), or "none" | ||||
| # (for no logging at all). console can be used only if compiled with debug | ||||
| # support. If logging is set to console, wMUD cannot be daemonized! | ||||
| log = console | ||||
| # if you wish, you can send debug, info, warning and error message to different | ||||
| # destinations by defining a "debug log", an "info log", a "warning log" and an | ||||
| # "error log" respectively | ||||
| #debug log = file:/home/polesz/Projektek/wMUD/data/debug.log | ||||
| info log = console | ||||
| warning log = console | ||||
| error log = console | ||||
| chat = yes | ||||
| dbus = yes | ||||
|  | ||||
| # after initialization, send into the background. This setting is automatically | ||||
| # set to "no" if logging is set to "console". However, if daemonize is set to | ||||
| # "force", wMUD will be sent to the background, and will be forced to log | ||||
| # through the syslog facilty | ||||
| daemonize = no | ||||
|  | ||||
| # wMUD is highly extensible with the use of modules | ||||
| [modules] | ||||
| # modules dir sets the place where module files can be found | ||||
| modules dir = /home/polesz/Projektek/wMUD/modules | ||||
| # the statesave module is used to save all the state of a running wMUD server. | ||||
| # Only one module can be specified here, and one MUST be specified. Without | ||||
| # such a module, wMUD won't be able to save character states, thus won't start | ||||
| # without one | ||||
| statesave = sqlite3 | ||||
| # wMUD doesn't speak any protocols on its own. Of course, several protocol | ||||
| # handler modules are provided with wMUD, and these can be loaded here. Module | ||||
| # names (thus, protocol names) can be separated by colons. At least one | ||||
| # protocol module must be loaded here. After startup, a client with | ||||
| # administrator privileges can load up more modules | ||||
| protocol = telnet:irc | ||||
|  | ||||
| # statesave * groups can have any keys and values, they won't get checked | ||||
| # during the configfile read. They are only processed by the state saving | ||||
| # module loaded in the modules group | ||||
|  | ||||
| [statesave sqlite3] | ||||
| # for the sqlite3 state saving module, only a state file must be specified | ||||
| state file = /home/polesz/Projektek/wMUD/data/state.sql | ||||
|  | ||||
| # similar to the statesave modules, protocol settings are also not checked | ||||
| # during initialization, only while actually loading up the modules. | ||||
|  | ||||
| # telnet interface on all interfaces' port 4000, with the timeout value of 10 | ||||
| # minutes | ||||
| [protocol telnet global] | ||||
| port = 4000 | ||||
| timeout = 600 | ||||
|  | ||||
| # telnet interface on localhost's port 9683 with the timeout value of 10 | ||||
| # minutes | ||||
| [protocol telnet local] | ||||
| address = 127.0.0.1 | ||||
| port = 9683 | ||||
| timeout = 600 | ||||
|  | ||||
| # IRC interface listening on all interfaces' port 6667, with no timeout value | ||||
| [protocol irc global] | ||||
| port = 6667 | ||||
|  | ||||
| # vim: ft=dosini | ||||
							
								
								
									
										6
									
								
								data/world.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								data/world.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <wmud> | ||||
| 	<world id="1"> | ||||
| 		<name>Iminiru</name> | ||||
| 	</world> | ||||
| </wmud> | ||||
							
								
								
									
										29
									
								
								doc/markup.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								doc/markup.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| All texts must conform to the following standards: | ||||
|  | ||||
| They must provide a valid XML is wrapped with this template: | ||||
|  | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <wmud> | ||||
| 	<formatted-text> | ||||
| 		THE TEXT ITSELF | ||||
| 	</formatted-text> | ||||
| </wmud> | ||||
|  | ||||
| Text can be formatted with the following tags: | ||||
| <normal>TEXT</normal>            - provides normal text (clears all formatting) | ||||
| <bold>TEXT</bold>                - provides bold text | ||||
| <underline>TEXT</underline>      - provides underlined text | ||||
| <COLOUR>TEXT</COLOUR>            - provides coloured text in the given colour, see below for exact tag names | ||||
|  | ||||
| Possible values for COLOUR: | ||||
| * black | ||||
| * red | ||||
| * green | ||||
| * yellow | ||||
| * blue | ||||
| * magenta | ||||
| * cyan | ||||
| * white | ||||
|  | ||||
| Please note that although most MUD clients support the above text formatting, some older terminals not. | ||||
| Also, for telnet-like clients, the text is wrapped into 78 columns after formatting has been applied. | ||||
							
								
								
									
										102
									
								
								doc/reference/libwmud-session/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								doc/reference/libwmud-session/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | ||||
| ## Process this file with automake to produce Makefile.in | ||||
|  | ||||
| # We require automake 1.6 at least. | ||||
| AUTOMAKE_OPTIONS = 1.6 | ||||
|  | ||||
| # This is a blank Makefile.am for using gtk-doc. | ||||
| # Copy this to your project's API docs directory and modify the variables to | ||||
| # suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples | ||||
| # of using the various options. | ||||
|  | ||||
| # The name of the module, e.g. 'glib'. | ||||
| DOC_MODULE=wmud-session | ||||
|  | ||||
| # Uncomment for versioned docs and specify the version of the module, e.g. '2'. | ||||
| DOC_MODULE_VERSION=1 | ||||
|  | ||||
|  | ||||
| # The top-level SGML file. You can change this if you want to. | ||||
| DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml | ||||
|  | ||||
| # The directory containing the source code. Relative to $(srcdir). | ||||
| # gtk-doc will search all .c & .h files beneath here for inline comments | ||||
| # documenting the functions and macros. | ||||
| # e.g. DOC_SOURCE_DIR=../../../gtk | ||||
| DOC_SOURCE_DIR=$(top_srcdir)/libwmud-session | ||||
|  | ||||
| # Extra options to pass to gtkdoc-scangobj. Not normally needed. | ||||
| SCANGOBJ_OPTIONS= | ||||
|  | ||||
| # Extra options to supply to gtkdoc-scan. | ||||
| # e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" | ||||
| SCAN_OPTIONS= | ||||
|  | ||||
| # Extra options to supply to gtkdoc-mkdb. | ||||
| # e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml | ||||
| MKDB_OPTIONS=--sgml-mode --output-format=xml | ||||
|  | ||||
| # Extra options to supply to gtkdoc-mktmpl | ||||
| # e.g. MKTMPL_OPTIONS=--only-section-tmpl | ||||
| MKTMPL_OPTIONS= | ||||
|  | ||||
| # Extra options to supply to gtkdoc-mkhtml | ||||
| MKHTML_OPTIONS= | ||||
|  | ||||
| # Extra options to supply to gtkdoc-fixref. Not normally needed. | ||||
| # e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html | ||||
| FIXXREF_OPTIONS= | ||||
|  | ||||
| # Used for dependencies. The docs will be rebuilt if any of these change. | ||||
| # e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h | ||||
| # e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c | ||||
| HFILE_GLOB= | ||||
| CFILE_GLOB= | ||||
|  | ||||
| # Extra header to include when scanning, which are not under DOC_SOURCE_DIR | ||||
| # e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h | ||||
| EXTRA_HFILES= | ||||
|  | ||||
| # Header files to ignore when scanning. Use base file name, no paths | ||||
| # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h | ||||
| IGNORE_HFILES= | ||||
|  | ||||
| # Images to copy into HTML directory. | ||||
| # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png | ||||
| HTML_IMAGES= | ||||
|  | ||||
| # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). | ||||
| # e.g. content_files=running.sgml building.sgml changes-2.0.sgml | ||||
| content_files= | ||||
|  | ||||
| # SGML files where gtk-doc abbrevations (#GtkWidget) are expanded | ||||
| # These files must be listed here *and* in content_files | ||||
| # e.g. expand_content_files=running.sgml | ||||
| expand_content_files= | ||||
|  | ||||
| # CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. | ||||
| # Only needed if you are using gtkdoc-scangobj to dynamically query widget | ||||
| # signals and properties. | ||||
| # e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) | ||||
| # e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) | ||||
| GTKDOC_CFLAGS=$(GLIB_CFLAGS) $(GOBJECT_CFLAGS) $(GNET_CFLAGS) | ||||
| GTKDOC_LIBS=$(GLIB_LIBS) $(GOBJECT_LIBS) $(GNET_LIBS) -L$(top_srcdir)/libwmud-session -lwmud-session-1.0 | ||||
|  | ||||
| # This includes the standard gtk-doc make rules, copied by gtkdocize. | ||||
| include $(top_srcdir)/gtk-doc.make | ||||
|  | ||||
| # Other files to distribute | ||||
| # e.g. EXTRA_DIST += version.xml.in | ||||
| EXTRA_DIST += | ||||
|  | ||||
| # Files not to distribute | ||||
| # for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types | ||||
| # for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt | ||||
| #DISTCLEANFILES += | ||||
|  | ||||
| # Comment this out if you want your docs-status tested during 'make check' | ||||
| if ENABLE_GTK_DOC | ||||
| #TESTS_ENVIRONMENT = cd $(srcsrc) && | ||||
| #TESTS = $(GTKDOC_CHECK) | ||||
| endif | ||||
|  | ||||
| -include $(top_srcdir)/git.mk | ||||
							
								
								
									
										32
									
								
								doc/reference/libwmud-session/wmud-session-docs.sgml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								doc/reference/libwmud-session/wmud-session-docs.sgml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| <?xml version="1.0"?> | ||||
| <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" | ||||
|                "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" | ||||
| [ | ||||
|   <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'"> | ||||
| ]> | ||||
| <book id="index"> | ||||
|   <bookinfo> | ||||
|     <title>wmud-session Reference Manual</title> | ||||
|     <releaseinfo> | ||||
|       for wmud-session [VERSION]. | ||||
|       The latest version of this documentation can be found on-line at | ||||
|       <ulink role="online-location" url="http://[SERVER]/wmud-session/index.html">http://[SERVER]/wmud-session/</ulink>. | ||||
|     </releaseinfo> | ||||
|   </bookinfo> | ||||
|  | ||||
|   <chapter> | ||||
|     <title>[Insert title here]</title> | ||||
|         <xi:include href="xml/wmud-session.xml"/> | ||||
|  | ||||
|   </chapter> | ||||
|   <chapter id="object-tree"> | ||||
|     <title>Object Hierarchy</title> | ||||
|      <xi:include href="xml/tree_index.sgml"/> | ||||
|   </chapter> | ||||
|   <index id="api-index-full"> | ||||
|     <title>API Index</title> | ||||
|     <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include> | ||||
|   </index> | ||||
|  | ||||
|   <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include> | ||||
| </book> | ||||
							
								
								
									
										19
									
								
								doc/reference/libwmud-session/wmud-session-sections.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								doc/reference/libwmud-session/wmud-session-sections.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| <SECTION> | ||||
| <FILE>wmud-session</FILE> | ||||
| <TITLE>wMUDSession</TITLE> | ||||
| wMUDSession | ||||
| wMUDSessionClass | ||||
| wMUDSessionPrivate | ||||
| wmud_session_new | ||||
| wmud_session_new_with_connection | ||||
| wmud_session_set_connection | ||||
| <SUBSECTION Standard> | ||||
| WMUD_SESSION | ||||
| WMUD_IS_SESSION | ||||
| WMUD_TYPE_SESSION | ||||
| wmud_session_get_type | ||||
| WMUD_SESSION_CLASS | ||||
| WMUD_IS_SESSION_CLASS | ||||
| WMUD_SESSION_GET_CLASS | ||||
| </SECTION> | ||||
|  | ||||
							
								
								
									
										102
									
								
								doc/reference/libwmud-world/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								doc/reference/libwmud-world/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | ||||
| ## Process this file with automake to produce Makefile.in | ||||
|  | ||||
| # We require automake 1.6 at least. | ||||
| AUTOMAKE_OPTIONS = 1.6 | ||||
|  | ||||
| # This is a blank Makefile.am for using gtk-doc. | ||||
| # Copy this to your project's API docs directory and modify the variables to | ||||
| # suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples | ||||
| # of using the various options. | ||||
|  | ||||
| # The name of the module, e.g. 'glib'. | ||||
| DOC_MODULE=wmud-world | ||||
|  | ||||
| # Uncomment for versioned docs and specify the version of the module, e.g. '2'. | ||||
| DOC_MODULE_VERSION=1 | ||||
|  | ||||
|  | ||||
| # The top-level SGML file. You can change this if you want to. | ||||
| DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml | ||||
|  | ||||
| # The directory containing the source code. Relative to $(srcdir). | ||||
| # gtk-doc will search all .c & .h files beneath here for inline comments | ||||
| # documenting the functions and macros. | ||||
| # e.g. DOC_SOURCE_DIR=../../../gtk | ||||
| DOC_SOURCE_DIR=$(top_srcdir)/libwmud-world | ||||
|  | ||||
| # Extra options to pass to gtkdoc-scangobj. Not normally needed. | ||||
| SCANGOBJ_OPTIONS= | ||||
|  | ||||
| # Extra options to supply to gtkdoc-scan. | ||||
| # e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" | ||||
| SCAN_OPTIONS= | ||||
|  | ||||
| # Extra options to supply to gtkdoc-mkdb. | ||||
| # e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml | ||||
| MKDB_OPTIONS=--sgml-mode --output-format=xml | ||||
|  | ||||
| # Extra options to supply to gtkdoc-mktmpl | ||||
| # e.g. MKTMPL_OPTIONS=--only-section-tmpl | ||||
| MKTMPL_OPTIONS= | ||||
|  | ||||
| # Extra options to supply to gtkdoc-mkhtml | ||||
| MKHTML_OPTIONS= | ||||
|  | ||||
| # Extra options to supply to gtkdoc-fixref. Not normally needed. | ||||
| # e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html | ||||
| FIXXREF_OPTIONS= | ||||
|  | ||||
| # Used for dependencies. The docs will be rebuilt if any of these change. | ||||
| # e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h | ||||
| # e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c | ||||
| HFILE_GLOB= | ||||
| CFILE_GLOB= | ||||
|  | ||||
| # Extra header to include when scanning, which are not under DOC_SOURCE_DIR | ||||
| # e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h | ||||
| EXTRA_HFILES= | ||||
|  | ||||
| # Header files to ignore when scanning. Use base file name, no paths | ||||
| # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h | ||||
| IGNORE_HFILES= | ||||
|  | ||||
| # Images to copy into HTML directory. | ||||
| # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png | ||||
| HTML_IMAGES= | ||||
|  | ||||
| # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). | ||||
| # e.g. content_files=running.sgml building.sgml changes-2.0.sgml | ||||
| content_files= | ||||
|  | ||||
| # SGML files where gtk-doc abbrevations (#GtkWidget) are expanded | ||||
| # These files must be listed here *and* in content_files | ||||
| # e.g. expand_content_files=running.sgml | ||||
| expand_content_files= | ||||
|  | ||||
| # CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. | ||||
| # Only needed if you are using gtkdoc-scangobj to dynamically query widget | ||||
| # signals and properties. | ||||
| # e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) | ||||
| # e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) | ||||
| GTKDOC_CFLAGS=$(GLIB_CFLAGS) $(GOBJECT_CFLAGS) $(GNET_CFLAGS) | ||||
| GTKDOC_LIBS=$(GLIB_LIBS) $(GOBJECT_LIBS) $(GNET_LIBS) -L$(top_srcdir)/libwmud-world -lwmud-world-1.0 | ||||
|  | ||||
| # This includes the standard gtk-doc make rules, copied by gtkdocize. | ||||
| include $(top_srcdir)/gtk-doc.make | ||||
|  | ||||
| # Other files to distribute | ||||
| # e.g. EXTRA_DIST += version.xml.in | ||||
| EXTRA_DIST += | ||||
|  | ||||
| # Files not to distribute | ||||
| # for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types | ||||
| # for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt | ||||
| #DISTCLEANFILES += | ||||
|  | ||||
| # Comment this out if you want your docs-status tested during 'make check' | ||||
| if ENABLE_GTK_DOC | ||||
| #TESTS_ENVIRONMENT = cd $(srcsrc) && | ||||
| #TESTS = $(GTKDOC_CHECK) | ||||
| endif | ||||
|  | ||||
| -include $(top_srcdir)/git.mk | ||||
							
								
								
									
										32
									
								
								doc/reference/libwmud-world/wmud-world-docs.sgml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								doc/reference/libwmud-world/wmud-world-docs.sgml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| <?xml version="1.0"?> | ||||
| <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" | ||||
|                "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" | ||||
| [ | ||||
|   <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'"> | ||||
| ]> | ||||
| <book id="index"> | ||||
|   <bookinfo> | ||||
|     <title>wmud-world Reference Manual</title> | ||||
|     <releaseinfo> | ||||
|       for wmud-world [VERSION]. | ||||
|       The latest version of this documentation can be found on-line at | ||||
|       <ulink role="online-location" url="http://[SERVER]/wmud-world/index.html">http://[SERVER]/wmud-world/</ulink>. | ||||
|     </releaseinfo> | ||||
|   </bookinfo> | ||||
|  | ||||
|   <chapter> | ||||
|     <title>[Insert title here]</title> | ||||
|         <xi:include href="xml/wmud-world.xml"/> | ||||
|  | ||||
|   </chapter> | ||||
|   <chapter id="object-tree"> | ||||
|     <title>Object Hierarchy</title> | ||||
|      <xi:include href="xml/tree_index.sgml"/> | ||||
|   </chapter> | ||||
|   <index id="api-index-full"> | ||||
|     <title>API Index</title> | ||||
|     <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include> | ||||
|   </index> | ||||
|  | ||||
|   <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include> | ||||
| </book> | ||||
							
								
								
									
										17
									
								
								doc/reference/libwmud-world/wmud-world-sections.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								doc/reference/libwmud-world/wmud-world-sections.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| <SECTION> | ||||
| <FILE>wmud-world</FILE> | ||||
| <TITLE>wMUDWorld</TITLE> | ||||
| wMUDWorld | ||||
| wMUDWorldClass | ||||
| wMUDWorldPrivate | ||||
| wmud_world_new | ||||
| <SUBSECTION Standard> | ||||
| WMUD_WORLD | ||||
| WMUD_IS_WORLD | ||||
| WMUD_TYPE_WORLD | ||||
| wmud_world_get_type | ||||
| WMUD_WORLD_CLASS | ||||
| WMUD_IS_WORLD_CLASS | ||||
| WMUD_WORLD_GET_CLASS | ||||
| </SECTION> | ||||
|  | ||||
							
								
								
									
										1
									
								
								doc/world.xsd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								doc/world.xsd
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
							
								
								
									
										6
									
								
								libwmud-protocol-telnet/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								libwmud-protocol-telnet/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| LIBWMUD_PROTOCOL_TELNET_VERSION=1:0:0 | ||||
| lib_LTLIBRARIES = libwmud-protocol-telnet-1.0.la | ||||
| libwmud_protocol_telnet_1_0_la_SOURCES = wmud-protocol-telnet.c | ||||
| libwmud_protocol_telnet_1_0_la_CFLAGS = $(CFLAGS) $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) $(GNET_CFLAGS) -Wall -I../src -I../libwmud-session | ||||
| libwmud_protocol_telnet_1_0_la_LIBADD = $(LIBS) $(GLIB_LIBS) $(GOBJECT_LIBS) $(GNET_LIBS) | ||||
| libwmud_protocol_telnet_1_0_la_LDFLAGS = -version-info $(LIBWMUD_PROTOCOL_TELNET_VERSION) | ||||
							
								
								
									
										102
									
								
								libwmud-protocol-telnet/wmud-protocol-telnet.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								libwmud-protocol-telnet/wmud-protocol-telnet.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | ||||
| #include "wmud-module.h" | ||||
|  | ||||
| gboolean | ||||
| wmud_protocol_telnet_load(wMUDConfiguration *configuration) | ||||
| { | ||||
| 	/* | ||||
| 	GSList *temp; | ||||
| 	wMUDConfigurationInterface *interface; | ||||
| 	gchar *iface_name; | ||||
| 	struct _wMUDIfaceFinder *finder; | ||||
|  | ||||
| 	finder = g_new0(struct _wMUDIfaceFinder, 1); | ||||
|  | ||||
| 	finder->type = WMUD_SESSION_TYPE_TELNET; | ||||
| 	finder->name = iface_name = g_utf8_offset_to_pointer(group, 7); | ||||
| 	Context; | ||||
| 	temp = g_slist_find_custom(conf->interfaces, finder, _wmud_find_iface); | ||||
| 	Context; | ||||
| 	g_free(finder); | ||||
|  | ||||
| 	if (temp == NULL) | ||||
| 	{ | ||||
| 		Context; | ||||
| 		interface = (wMUDConfigurationInterface *)g_new0(wMUDConfigurationInterface, 1); | ||||
| 		interface->name = g_strdup(iface_name); | ||||
| 		interface->type = WMUD_SESSION_TYPE_TELNET; | ||||
| 		conf->interfaces = g_slist_append(conf->interfaces, interface); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		Context; | ||||
| 		interface = (wMUDConfigurationInterface *)(temp->data); | ||||
| 	} | ||||
|  | ||||
| 	if (g_utf8_collate("port", key) == 0) | ||||
| 	{ | ||||
| 		guint64 portnumber; | ||||
| 		gchar *endptr; | ||||
|  | ||||
| 		portnumber = g_ascii_strtoull(value, &endptr, 10); | ||||
|  | ||||
| 		if ((endptr != NULL) && (*endptr != 0)) | ||||
| 		{ | ||||
| 			wmud_log_error("Error in configuration file. Value of port can only contain numbers in group [%s]!", group); | ||||
| 		} | ||||
|  | ||||
| 		if (interface->inetaddr == NULL) | ||||
| 		{ | ||||
| 			interface->inetaddr = gnet_inetaddr_new("0.0.0.0", portnumber); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			gnet_inetaddr_set_port(interface->inetaddr, (gint)portnumber); | ||||
| 		} | ||||
|  | ||||
| 		g_pattern_spec_free(group_ptn); | ||||
| 		return TRUE; | ||||
| 	} | ||||
|  | ||||
| 	if (g_utf8_collate("address", key) == 0) | ||||
| 	{ | ||||
| 		GInetAddr *temp = gnet_inetaddr_new(value, 0); | ||||
|  | ||||
| 		if (interface->inetaddr) | ||||
| 		{ | ||||
| 			gnet_inetaddr_set_port(temp, gnet_inetaddr_get_port(interface->inetaddr)); | ||||
| 			gnet_inetaddr_unref(interface->inetaddr); | ||||
| 			interface->inetaddr = NULL; | ||||
| 		} | ||||
| 		interface->inetaddr = temp; | ||||
|  | ||||
| 		g_pattern_spec_free(group_ptn); | ||||
| 		return TRUE; | ||||
| 	} | ||||
|  | ||||
| 	if (g_utf8_collate("timeout", key) == 0) | ||||
| 	{ | ||||
| 		guint64 timeout; | ||||
| 		gchar *endptr; | ||||
|  | ||||
| 		timeout = g_ascii_strtoull(value, &endptr, 10); | ||||
|  | ||||
| 		if ((endptr != NULL) && (*endptr != 0)) | ||||
| 		{ | ||||
| 			wmud_log_error("Error in configuration file. Value of timeout can only contain numbers! in group [%s]", group); | ||||
| 		} | ||||
|  | ||||
| 		interface->timeout = (guint)timeout; | ||||
|  | ||||
| 		g_pattern_spec_free(group_ptn); | ||||
| 		return TRUE; | ||||
| 	} | ||||
| 	*/ | ||||
|  | ||||
| 	return TRUE; | ||||
| } | ||||
|  | ||||
| void | ||||
| wmud_protocol_telnet_unload(void) | ||||
| { | ||||
| } | ||||
|  | ||||
							
								
								
									
										0
									
								
								libwmud-protocol-telnet/wmud-protocol-telnet.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								libwmud-protocol-telnet/wmud-protocol-telnet.h
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										6
									
								
								libwmud-session/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								libwmud-session/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| LIBWMUD_SESSION_VERSION=1:0:0 | ||||
| lib_LTLIBRARIES = libwmud-session-1.0.la | ||||
| libwmud_session_1_0_la_SOURCES = wmud-session.c | ||||
| libwmud_session_1_0_la_CFLAGS = $(CFLAGS) $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) $(GNET_CFLAGS) -Wall | ||||
| libwmud_session_1_0_la_LIBADD = $(LIBS) $(GLIB_LIBS) $(GOBJECT_LIBS) $(GNET_LIBS) | ||||
| libwmud_session_1_0_la_LDFLAGS = -version-info $(LIBWMUD_SESSION_VERSION) | ||||
							
								
								
									
										304
									
								
								libwmud-session/wmud-session.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										304
									
								
								libwmud-session/wmud-session.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,304 @@ | ||||
| /* wMUDSession - wMUD Session handler object | ||||
|  * Copyright (C) 2010, Gergely Polonkai | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library 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 | ||||
|  * Lesser General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Lesser General | ||||
|  * Public License along with this library; if not, write to the | ||||
|  * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | ||||
|  * Boston, MA 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #include <gnet.h> | ||||
|  | ||||
| #include "wmud-session.h" | ||||
|  | ||||
| /** SECTION:objects | ||||
|  * @short_description: wMUD Session object | ||||
|  * @title: wMUD Session handler object | ||||
|  * | ||||
|  * wMUDSession is an object to store session-related information in | ||||
|  * wMUD | ||||
|  */ | ||||
|  | ||||
| /* --- macros --- */ | ||||
| #define WMUD_SESSION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), WMUD_TYPE_SESSION, wMUDSessionPrivate)) | ||||
|  | ||||
| /* --- structures --- */ | ||||
|  | ||||
| struct _wMUDSessionPrivate | ||||
| { | ||||
| 	GConn *connection; | ||||
| 	wMUDSessionType type; | ||||
| }; | ||||
|  | ||||
| /* --- signals --- */ | ||||
|  | ||||
| /* --- properties --- */ | ||||
| enum | ||||
| { | ||||
| 	PROP_0, | ||||
| 	PROP_CONNECTION, | ||||
| 	PROP_TYPE | ||||
| }; | ||||
|  | ||||
| /* --- prototypes --- */ | ||||
| static void wmud_session_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); | ||||
| static void wmud_session_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); | ||||
| static void wmud_session_dispose(GObject *object); | ||||
| static void wmud_session_finalize(GObject *object); | ||||
| static void wmud_session_class_init(wMUDSessionClass *klass); | ||||
| static void wmud_session_init(wMUDSession *self); | ||||
| wMUDSession *wmud_session_new(void); | ||||
| wMUDSession *wmud_session_new_with_connection(GConn *connection); | ||||
| GConn *wmud_session_get_connection(wMUDSession *session); | ||||
| void wmud_session_set_connection(wMUDSession *session, GConn *connection); | ||||
| wMUDSessionType wmud_session_get_session_type(wMUDSession *session); | ||||
| void wmud_session_set_session_type(wMUDSession *session, wMUDSessionType type); | ||||
|  | ||||
| /* --- variables --- */ | ||||
|  | ||||
| /* --- functions --- */ | ||||
|  | ||||
| G_DEFINE_TYPE(wMUDSession, wmud_session, G_TYPE_OBJECT); | ||||
|  | ||||
| #define WMUD_TYPE_SESSION_TYPE       wmud_session_type_get_type() | ||||
| static GType | ||||
| wmud_session_type_get_type(void) | ||||
| { | ||||
| 	static GType wmud_session_type_type = 0; | ||||
| 	static const GEnumValue wmud_session_types[] = { | ||||
| 		{ WMUD_SESSION_TYPE_UNKNOWN, "Unknown session type", "unknown" }, | ||||
| 		{ WMUD_SESSION_TYPE_TELNET,  "Telnet session",       "telnet" }, | ||||
| 		{ 0, NULL, NULL } | ||||
| 	}; | ||||
|  | ||||
| 	if (!wmud_session_type_type) | ||||
| 	{ | ||||
| 		wmud_session_type_type = g_enum_register_static("wMUDSessionType", wmud_session_types); | ||||
| 	} | ||||
|  | ||||
| 	return wmud_session_type_type; | ||||
| } | ||||
|  | ||||
| static void | ||||
| wmud_session_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) | ||||
| { | ||||
| 	wMUDSession *self = WMUD_SESSION(object); | ||||
|  | ||||
| 	switch (property_id) | ||||
| 	{ | ||||
| 		case PROP_CONNECTION: | ||||
| 			if (self->priv->connection) | ||||
| 			{ | ||||
| 				gnet_conn_unref(self->priv->connection); | ||||
| 			} | ||||
| 			self->priv->connection = (GConn *)g_value_get_pointer(value); | ||||
| 			if (self->priv->connection) | ||||
| 			{ | ||||
| 				gnet_conn_ref(self->priv->connection); | ||||
| 			} | ||||
| 			break; | ||||
| 		case PROP_TYPE: | ||||
| 			self->priv->type = g_value_get_enum(value); | ||||
| 			break; | ||||
| 		default: | ||||
| 			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void | ||||
| wmud_session_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) | ||||
| { | ||||
| 	wMUDSession *self = WMUD_SESSION(object); | ||||
|  | ||||
| 	switch (property_id) | ||||
| 	{ | ||||
| 		case PROP_CONNECTION: | ||||
| 			g_value_set_pointer(value, self->priv->connection); | ||||
| 			break; | ||||
| 		case PROP_TYPE: | ||||
| 			g_value_set_enum(value, self->priv->type); | ||||
| 			break; | ||||
| 		default: | ||||
| 			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void | ||||
| wmud_session_dispose(GObject *object) | ||||
| { | ||||
| 	G_OBJECT_CLASS(wmud_session_parent_class)->dispose(object); | ||||
| } | ||||
|  | ||||
| static void | ||||
| wmud_session_finalize(GObject *object) | ||||
| { | ||||
| 	wMUDSession *self = WMUD_SESSION(object); | ||||
|  | ||||
| 	if (self->priv->connection) | ||||
| 	{ | ||||
| 		gnet_conn_disconnect(self->priv->connection); | ||||
| 		gnet_conn_unref(self->priv->connection); | ||||
| 		self->priv->connection = NULL; | ||||
| 	} | ||||
|  | ||||
| 	G_OBJECT_CLASS(wmud_session_parent_class)->finalize(object); | ||||
| } | ||||
|  | ||||
| static void | ||||
| wmud_session_class_init(wMUDSessionClass *klass) | ||||
| { | ||||
| 	GObjectClass *gobject_class = G_OBJECT_CLASS(klass); | ||||
| 	GParamSpec *wmud_session_param_spec; | ||||
|  | ||||
| 	gobject_class->set_property = wmud_session_set_property; | ||||
| 	gobject_class->get_property = wmud_session_get_property; | ||||
| 	gobject_class->dispose      = wmud_session_dispose; | ||||
| 	gobject_class->finalize     = wmud_session_finalize; | ||||
|  | ||||
| 	g_type_class_add_private(klass, sizeof(wMUDSessionPrivate)); | ||||
|  | ||||
| 	wmud_session_param_spec = g_param_spec_pointer("connection", "Connection handle", "GConn * handle of the connection", G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); | ||||
| 	g_object_class_install_property(gobject_class, PROP_CONNECTION, wmud_session_param_spec); | ||||
|  | ||||
| 	wmud_session_param_spec = g_param_spec_enum("type", "SessionType", "Type of the session's connection", WMUD_TYPE_SESSION_TYPE, WMUD_SESSION_TYPE_UNKNOWN, G_PARAM_READWRITE); | ||||
| 	g_object_class_install_property(gobject_class, PROP_TYPE, wmud_session_param_spec); | ||||
| } | ||||
|  | ||||
| static void | ||||
| wmud_session_init(wMUDSession *self) | ||||
| { | ||||
| 	wMUDSessionPrivate *priv; | ||||
|  | ||||
| 	self->priv = priv = WMUD_SESSION_GET_PRIVATE(self); | ||||
|  | ||||
| 	priv->connection = NULL; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * wmud_session_new: | ||||
|  * | ||||
|  * Creates a new wMUDSession object | ||||
|  * | ||||
|  * Returns: a new instance of wMUDSession | ||||
|  */ | ||||
| wMUDSession * | ||||
| wmud_session_new(void) | ||||
| { | ||||
| 	wMUDSession *new_session = g_object_new(WMUD_TYPE_SESSION, NULL); | ||||
|  | ||||
| 	return new_session; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * wmud_session_new_with_connection: | ||||
|  * @connection: the connection this session is bound to. This object is | ||||
|  *  g_unref()'d when the Session object is disposed | ||||
|  * | ||||
|  * Returns: a new instance of wMUDSession with the connection property set | ||||
|  */ | ||||
| wMUDSession * | ||||
| wmud_session_new_with_connection(GConn *connection) | ||||
| { | ||||
| 	wMUDSession *new_session = g_object_new(WMUD_TYPE_SESSION, "connection", connection, NULL); | ||||
| 	wmud_session_set_connection(new_session, connection); | ||||
|  | ||||
| 	return new_session; | ||||
| } | ||||
|  | ||||
| GConn * | ||||
| wmud_session_get_connection(wMUDSession *session) | ||||
| { | ||||
| 	GConn *connection = NULL; | ||||
| 	GValue value = {0}; | ||||
|  | ||||
| 	g_value_init(&value, G_TYPE_POINTER); | ||||
|  | ||||
| 	wmud_session_get_property(G_OBJECT(session), PROP_CONNECTION, &value, NULL); | ||||
|  | ||||
| 	connection = g_value_get_pointer(&value); | ||||
|  | ||||
| 	g_value_unset(&value); | ||||
|  | ||||
| 	return connection; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * wmud_session_set_connection: | ||||
|  * @session: the object which should receive the new connection | ||||
|  * @connection: the connection this session should be bound to. This object is g_unref()'d when the Session object is disposed | ||||
|  */ | ||||
| void | ||||
| wmud_session_set_connection(wMUDSession *session, GConn *connection) | ||||
| { | ||||
| 	GValue value = {0}; | ||||
|  | ||||
| 	g_value_init(&value, G_TYPE_POINTER); | ||||
| 	g_value_set_pointer(&value, (gpointer)connection); | ||||
|  | ||||
| 	wmud_session_set_property(G_OBJECT(session), PROP_CONNECTION, &value, NULL); | ||||
|  | ||||
| 	g_value_unset(&value); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * wmud_session_has_connection: | ||||
|  * @session: the object which should be inspected | ||||
|  * @connection: the connection we are looking for | ||||
|  * | ||||
|  * Checks if the given #wMUDSession has the given #GConn connection | ||||
|  * | ||||
|  * Returns: %TRUE, if the connection is owned by this session, %FALSE otherwise | ||||
|  */ | ||||
| gboolean | ||||
| wmud_session_has_connection(wMUDSession *session, GConn *connection) | ||||
| { | ||||
| 	if (session->priv->connection == connection) | ||||
| 		return TRUE; | ||||
|  | ||||
| 	return FALSE; | ||||
| } | ||||
|  | ||||
| wMUDSessionType | ||||
| wmud_session_get_session_type(wMUDSession *session) | ||||
| { | ||||
| 	GValue value = {0}; | ||||
| 	g_value_init(&value, WMUD_TYPE_SESSION_TYPE); | ||||
|  | ||||
| 	wmud_session_get_property(G_OBJECT(session), PROP_TYPE, &value, NULL); | ||||
|  | ||||
| 	return g_value_get_enum(&value); | ||||
| } | ||||
|  | ||||
| void | ||||
| wmud_session_set_session_type(wMUDSession *session, wMUDSessionType type) | ||||
| { | ||||
| 	GValue value = {0, }; | ||||
| 	g_value_init(&value, WMUD_TYPE_SESSION_TYPE); | ||||
|  | ||||
| 	g_value_set_enum(&value, type); | ||||
| 	wmud_session_set_property(G_OBJECT(session), PROP_TYPE, &value, NULL); | ||||
| } | ||||
|  | ||||
| wMUDSession * | ||||
| wmud_session_ref(wMUDSession *session) | ||||
| { | ||||
| 	return WMUD_SESSION(g_object_ref(G_OBJECT(session))); | ||||
| } | ||||
|  | ||||
| void | ||||
| wmud_session_unref(wMUDSession *session) | ||||
| { | ||||
| 	g_object_unref(G_OBJECT(session)); | ||||
| } | ||||
							
								
								
									
										53
									
								
								libwmud-session/wmud-session.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								libwmud-session/wmud-session.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| #ifndef __WMUD_SESSION_H__ | ||||
| #define __WMUD_SESSION_H__ | ||||
|  | ||||
| #include <glib.h> | ||||
| #include <glib-object.h> | ||||
| #include <gnet.h> | ||||
|  | ||||
| #define WMUD_TYPE_SESSION            wmud_session_get_type() | ||||
| #define WMUD_SESSION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), WMUD_TYPE_SESSION, wMUDSession)) | ||||
| #define WMUD_IS_SESSION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), WMUD_TYPE_SESSION)) | ||||
| #define WMUD_SESSION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), WMUD_TYPE_SESSION, wMUDSessionClass)) | ||||
| #define WMUD_IS_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WMUD_TYPE_SESSION)) | ||||
| #define WMUD_SESSION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), WMUD_TYPE_SESSION, wMUDSessionClass)) | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
| 	WMUD_SESSION_TYPE_UNKNOWN, | ||||
| 	WMUD_SESSION_TYPE_TELNET, | ||||
| 	WMUD_SESSION_TYPE_IRC, | ||||
| 	WMUD_SESSION_TYPE_HTTP | ||||
| } wMUDSessionType; | ||||
|  | ||||
| typedef struct _wMUDSession        wMUDSession; | ||||
| typedef struct _wMUDSessionClass   wMUDSessionClass; | ||||
| typedef struct _wMUDSessionPrivate wMUDSessionPrivate; | ||||
|  | ||||
| struct _wMUDSession | ||||
| { | ||||
| 	GObject parent_object; | ||||
| 	 | ||||
| 	wMUDSessionPrivate *priv; | ||||
| }; | ||||
|  | ||||
| struct _wMUDSessionClass | ||||
| { | ||||
| 	GObjectClass parent_class; | ||||
| }; | ||||
|  | ||||
| GType wmud_session_get_type(void); | ||||
|  | ||||
| wMUDSession *wmud_session_new(void); | ||||
| wMUDSession *wmud_session_new_with_connection(GConn *connection); | ||||
| gboolean wmud_session_has_connection(wMUDSession *session, GConn *connection); | ||||
| wMUDSession *wmud_session_ref(wMUDSession *session); | ||||
| void wmud_session_unref(wMUDSession *session); | ||||
|  | ||||
| GConn *wmud_session_get_connection(wMUDSession *session); | ||||
| void wmud_session_set_connection(wMUDSession *session, GConn *connection); | ||||
| wMUDSessionType wmud_session_get_session_type(wMUDSession *session); | ||||
| void wmud_session_set_session_type(wMUDSession *session, wMUDSessionType type); | ||||
|  | ||||
| #endif /* __WMUD_SESSION_H__ */ | ||||
|  | ||||
							
								
								
									
										11
									
								
								libwmud-session/wmud-session.pc.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								libwmud-session/wmud-session.pc.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| prefix=@prefix@ | ||||
| exec_prefix=@exec_prefix@ | ||||
| libdir=@libdir@ | ||||
| includedir=@includedir@ | ||||
|  | ||||
| Name: wMUDSession | ||||
| Description: Library to handle wMUD sessions | ||||
| Requires: glib-2.0 gobject-2.0 | ||||
| Version: PACKAGE_VERSION | ||||
| Libs: -L${libdir} -lwmud-session-1.0 | ||||
| Cflags: -I${includedir}/wmud-session -I${libdir}/wmud-session/include | ||||
							
								
								
									
										6
									
								
								libwmud-state-sqlite3/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								libwmud-state-sqlite3/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| LIBWMUD_STATE_SQLITE3_VERSION=1:0:0 | ||||
| lib_LTLIBRARIES = libwmud-state-sqlite3-1.0.la | ||||
| libwmud_state_sqlite3_1_0_la_SOURCES = wmud-state-sqlite3.c | ||||
| libwmud_state_sqlite3_1_0_la_CFLAGS = $(CFLAGS) $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) $(GNET_CFLAGS) -Wall -I../src -I../libwmud-session | ||||
| libwmud_state_sqlite3_1_0_la_LIBADD = $(LIBS) $(GLIB_LIBS) $(GOBJECT_LIBS) $(GNET_LIBS) | ||||
| libwmud_state_sqlite3_1_0_la_LDFLAGS = -version-info $(LIBWMUD_STATE_SQLITE3_VERSION) | ||||
							
								
								
									
										91
									
								
								libwmud-state-sqlite3/wmud-state-sqlite3.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								libwmud-state-sqlite3/wmud-state-sqlite3.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | ||||
| #include <glib.h> | ||||
| #include <sqlite3.h> | ||||
|  | ||||
| #ifdef HAVE_CONFIG_H | ||||
| #include "config.h" | ||||
| #endif | ||||
|  | ||||
| #include "module.h" | ||||
|  | ||||
| static gchar *state_file = NULL; | ||||
| static sqlite3 *statesave_connection = NULL; | ||||
|  | ||||
| gboolean | ||||
| wmud_statesave_sqlite3_is_statesave(void) | ||||
| { | ||||
| 	return TRUE; | ||||
| } | ||||
|  | ||||
| static gint | ||||
| _wmud_statesave_sqlite3_find_config_group(gconstpointer list_data, gconstpointer lookup_data) | ||||
| { | ||||
| 	wMUDConfigurationGroup *group = (wMUDConfigurationGroup *)list_data; | ||||
| 	gchar *name_to_find = (gchar *)lookup_data; | ||||
|  | ||||
| 	Context return g_utf8_collate(group->name, name_to_find); | ||||
| } | ||||
|  | ||||
| static void | ||||
| _wmud_statesave_sqlite3_parse_config(gpointer data, gpointer userdata) | ||||
| { | ||||
| 	wMUDConfigurationValue *parameter = (wMUDConfigurationValue *)data; | ||||
|  | ||||
| 	if (g_utf8_collate("state file", parameter->key) == 0) | ||||
| 	{ | ||||
| 		state_file = g_strdup(parameter->value); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| wmud_statesave_sqlite3_load(wMUDConfiguration *config) | ||||
| { | ||||
| 	GSList *statesave_params; | ||||
| 	wMUDConfigurationGroup *config_group; | ||||
|  | ||||
| 	wmud_log_debug("Initializing SQLite3 state saving module..."); | ||||
|  | ||||
| 	if (!sqlite3_threadsafe()) | ||||
| 	{ | ||||
| 		wmud_log_error("SQLite3 library is not compiled in a thread-safe manner."); | ||||
| 		return FALSE; | ||||
| 	} | ||||
|  | ||||
| 	Context statesave_params = g_slist_find_custom(config->statesave_parameters, "sqlite3", _wmud_statesave_sqlite3_find_config_group); | ||||
|  | ||||
| 	if (statesave_params == NULL) | ||||
| 	{ | ||||
| 		wmud_log_error("Cannot find group [statesave sqlite3] in configfile!"); | ||||
| 		return FALSE; | ||||
| 	} | ||||
|  | ||||
| 	config_group = (wMUDConfigurationGroup *)(statesave_params->data); | ||||
| 	g_slist_foreach(config_group->datalist, _wmud_statesave_sqlite3_parse_config, NULL); | ||||
|  | ||||
| 	if (state_file == NULL) | ||||
| 	{ | ||||
| 		wmud_log_error("Cannot find state file parameter in configuration file (should be under group [statesave sqlite3]"); | ||||
| 		return FALSE; | ||||
| 	} | ||||
|  | ||||
| 	wmud_log_debug("Will save state into SQLite3 file %s", state_file); | ||||
|  | ||||
| 	switch (sqlite3_open(state_file, &statesave_connection)) | ||||
| 	{ | ||||
| 		case SQLITE_OK: | ||||
| 			wmud_log_info("State file opened successfully"); | ||||
| 			break; | ||||
| 		default: | ||||
| 			wmud_log_error("Unprocessed return value from sqlite3_open()!"); | ||||
| 			return FALSE; | ||||
| 			break; | ||||
| 	} | ||||
|  | ||||
| 	return TRUE; | ||||
| } | ||||
|  | ||||
| void | ||||
| wmud_statesave_sqlite3_unload(void) | ||||
| { | ||||
| 	sqlite3_close(statesave_connection); | ||||
| } | ||||
|  | ||||
							
								
								
									
										0
									
								
								libwmud-state-sqlite3/wmud-state-sqlite3.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								libwmud-state-sqlite3/wmud-state-sqlite3.h
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										4
									
								
								libwmud-world/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								libwmud-world/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| lib_LTLIBRARIES = libwmud-world-1.0.la | ||||
| libwmud_world_1_0_la_SOURCES = wmud-world.c | ||||
| libwmud_world_1_0_la_CFLAGS = $(CFLAGS) $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) $(GNET_CFLAGS) -Wall | ||||
| libwmud_world_1_0_la_LIBADD = $(LIBS) $(GLIB_LIBS) $(GOBJECT_LIBS) $(GNET_LIBS) | ||||
							
								
								
									
										104
									
								
								libwmud-world/wmud-world.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								libwmud-world/wmud-world.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | ||||
| #include "wmud-world.h" | ||||
|  | ||||
| #define WMUD_WORLD_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), WMUD_TYPE_WORLD, wMUDWorldPrivate)) | ||||
|  | ||||
| struct _wMUDWorldPrivate | ||||
| { | ||||
| 	gchar *name; | ||||
| }; | ||||
|  | ||||
| enum | ||||
| { | ||||
| 	PROP_0, | ||||
| 	PROP_NAME | ||||
| }; | ||||
|  | ||||
| G_DEFINE_TYPE(wMUDWorld, wmud_world, G_TYPE_OBJECT); | ||||
|  | ||||
| static void | ||||
| wmud_world_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) | ||||
| { | ||||
| 	wMUDWorld *self = WMUD_WORLD(object); | ||||
|  | ||||
| 	switch (property_id) | ||||
| 	{ | ||||
| 		case PROP_NAME: | ||||
| 			g_free(self->priv->name); | ||||
| 			self->priv->name = g_value_dup_string(value); | ||||
| 			break; | ||||
| 		default: | ||||
| 			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void | ||||
| wmud_world_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) | ||||
| { | ||||
| 	wMUDWorld *self = WMUD_WORLD(object); | ||||
|  | ||||
| 	switch (property_id) | ||||
| 	{ | ||||
| 		case PROP_NAME: | ||||
| 			g_value_set_string(value, self->priv->name); | ||||
| 			break; | ||||
| 		default: | ||||
| 			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void | ||||
| wmud_world_dispose(GObject *object) | ||||
| { | ||||
| 	G_OBJECT_CLASS(wmud_world_parent_class)->dispose(object); | ||||
| } | ||||
|  | ||||
| static void | ||||
| wmud_world_finalize(GObject *object) | ||||
| { | ||||
| 	wMUDWorld *self = WMUD_WORLD(object); | ||||
|  | ||||
| 	if (self->priv->name) | ||||
| 	{ | ||||
| 		g_free(self->priv->name); | ||||
| 	} | ||||
|  | ||||
| 	G_OBJECT_CLASS(wmud_world_parent_class)->finalize(object); | ||||
| } | ||||
|  | ||||
| static void | ||||
| wmud_world_class_init(wMUDWorldClass *klass) | ||||
| { | ||||
| 	GObjectClass *gobject_class = G_OBJECT_CLASS(klass); | ||||
| 	GParamSpec *wmud_world_param_spec; | ||||
|  | ||||
| 	gobject_class->set_property = wmud_world_set_property; | ||||
| 	gobject_class->get_property = wmud_world_get_property; | ||||
| 	gobject_class->dispose      = wmud_world_dispose; | ||||
| 	gobject_class->finalize     = wmud_world_finalize; | ||||
|  | ||||
| 	g_type_class_add_private(klass, sizeof(wMUDWorldPrivate)); | ||||
|  | ||||
| 	wmud_world_param_spec = g_param_spec_string("name", "World name", "Set the name of the world", NULL, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); | ||||
| 	g_object_class_install_property(gobject_class, PROP_NAME, wmud_world_param_spec); | ||||
| } | ||||
|  | ||||
| static void | ||||
| wmud_world_init(wMUDWorld *self) | ||||
| { | ||||
| 	wMUDWorldPrivate *priv; | ||||
|  | ||||
| 	self->priv = priv = WMUD_WORLD_GET_PRIVATE(self); | ||||
|  | ||||
| 	priv->name = NULL; | ||||
| } | ||||
|  | ||||
| wMUDWorld * | ||||
| wmud_world_new(void) | ||||
| { | ||||
| 	wMUDWorld *new_world = g_object_new(WMUD_TYPE_WORLD, NULL); | ||||
|  | ||||
| 	return new_world; | ||||
| } | ||||
|  | ||||
							
								
								
									
										34
									
								
								libwmud-world/wmud-world.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								libwmud-world/wmud-world.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| #ifndef __WMUD_WORLD_H__ | ||||
| #define __WMUD_WORLD_H__ | ||||
|  | ||||
| #include <glib-object.h> | ||||
|  | ||||
| #define WMUD_TYPE_WORLD            wmud_world_get_type() | ||||
| #define WMUD_WORLD(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), WMUD_TYPE_WORLD, wMUDWorld)) | ||||
| #define WMUD_IS_WORLD(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), WMUD_TYPE_WORLD)) | ||||
| #define WMUD_WORLD_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), WMUD_TYPE_WORLD, wMUDWorldClass)) | ||||
| #define WMUD_IS_WORLD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WMUD_TYPE_WORLD)) | ||||
| #define WMUD_WORLD_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), WMUD_TYPE_WORLD, wMUDWorldClass)) | ||||
|  | ||||
| typedef struct _wMUDWorld        wMUDWorld; | ||||
| typedef struct _wMUDWorldClass   wMUDWorldClass; | ||||
| typedef struct _wMUDWorldPrivate wMUDWorldPrivate; | ||||
|  | ||||
| struct _wMUDWorld | ||||
| { | ||||
| 	GObject parent_object; | ||||
| 	 | ||||
| 	wMUDWorldPrivate *priv; | ||||
| }; | ||||
|  | ||||
| struct _wMUDWorldClass | ||||
| { | ||||
| 	GObjectClass parent_class; | ||||
| }; | ||||
|  | ||||
| GType wmud_world_get_type(void); | ||||
|  | ||||
| wMUDWorld *wmud_world_new(void); | ||||
|  | ||||
| #endif /* __WMUD_WORLD_H__ */ | ||||
|  | ||||
							
								
								
									
										4
									
								
								src/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| bin_PROGRAMS = wmud | ||||
| wmud_SOURCES = wmud.c logger.c ansi.c networking.c world.c sessions.c configfile.c commands.c chat.c irc.c modules.c | ||||
| wmud_CFLAGS = $(CFLAGS) $(EXTLIBS_CFLAGS) -I../libwmud-session -I../libwmud-world -Wall | ||||
| wmud_LDADD = $(LIBS) $(EXTLIBS_LIBS) -L../libwmud-session -lwmud-session-1.0 -L../libwmud-world -lwmud-world-1.0 | ||||
							
								
								
									
										104
									
								
								src/ansi.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								src/ansi.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | ||||
| #include <glib.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include "ansi.h" | ||||
|  | ||||
| typedef struct _wmud_tag_to_ansi { | ||||
| 	gchar *open_tag; | ||||
| 	gint open_tag_length; | ||||
| 	gchar *close_tag; | ||||
| 	gint close_tag_length; | ||||
| 	gchar *ansi_sequence; | ||||
| } wmud_tag_to_ansi; | ||||
|  | ||||
| static wmud_tag_to_ansi tags[] = { | ||||
| 	{ "<bold>",                 6,  "</bold>",      7,  ANSI_BOLD }, | ||||
| 	{ "<underline>",            11, "</underline>", 12, ANSI_UNDERLINE }, | ||||
| 	{ "<normal>",               8,  "</normal>",    9,  ANSI_NORMAL }, | ||||
| 	{ "<black>",                7,  "</black>",     8,  ANSI_COLOR_BLACK }, | ||||
| 	{ "<red>",                  5,  "</red>",       6,  ANSI_COLOR_RED }, | ||||
| 	{ "<green>",                7,  "</green>",     8,  ANSI_COLOR_GREEN }, | ||||
| 	{ "<yellow>",               8,  "</yellow>",    9,  ANSI_COLOR_YELLOW }, | ||||
| 	{ "<blue>",                 6,  "</blue>",      7,  ANSI_COLOR_BLUE }, | ||||
| 	{ "<magenta>",              9,  "</magenta>",   10, ANSI_COLOR_MAGENTA }, | ||||
| 	{ "<cyan>",                 6,  "</cyan>",      7,  ANSI_COLOR_CYAN }, | ||||
| 	{ "<white>",                7,  "</colour>",    8,  ANSI_COLOR_WHITE }, | ||||
| }; | ||||
|  | ||||
| static void | ||||
| _str_append_string(gchar **dest, gchar *src) | ||||
| { | ||||
| 	gchar *temp; | ||||
|  | ||||
| 	temp = g_strdup(*dest); | ||||
| 	*dest = g_strdup_printf("%s%s", temp, src); | ||||
| 	g_free(temp); | ||||
| } | ||||
|  | ||||
| static void | ||||
| _str_append_char(gchar **dest, gchar src) | ||||
| { | ||||
| 	gchar *temp; | ||||
|  | ||||
| 	temp = g_strdup(*dest); | ||||
| 	*dest = g_strdup_printf("%s%c", temp, src); | ||||
| 	g_free(temp); | ||||
| } | ||||
|  | ||||
| static void | ||||
| _add_remaining_formatters(gpointer element, gpointer data) | ||||
| { | ||||
|  | ||||
| 	_str_append_string(data, (gchar *)element); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| wmud_text_to_ansi(gchar *text, gchar **result) | ||||
| { | ||||
| 	gchar *a; | ||||
| 	GSList *current_formatters = NULL; | ||||
| 	gchar *r = g_strdup(""); | ||||
|  | ||||
| 	for (a = text; *a; a++) | ||||
| 	{ | ||||
| 		gint i; | ||||
| 		gboolean found = FALSE; | ||||
|  | ||||
| 		for (i = 0; i < sizeof(tags) / sizeof(wmud_tag_to_ansi); i++) | ||||
| 		{ | ||||
| 			if (g_strncasecmp(a, tags[i].open_tag, tags[i].open_tag_length) == 0) | ||||
| 			{ | ||||
| 				_str_append_string(&r, tags[i].ansi_sequence); | ||||
|  | ||||
| 				current_formatters = g_slist_append(current_formatters, tags[i].ansi_sequence); | ||||
| 				a += tags[i].open_tag_length - 1; | ||||
| 				found = TRUE; | ||||
| 				break; | ||||
| 			} | ||||
| 			if (g_strncasecmp(a, tags[i].close_tag, tags[i].close_tag_length) == 0) | ||||
| 			{ | ||||
| 				_str_append_string(&r, ANSI_NORMAL); | ||||
|  | ||||
| 				current_formatters = g_slist_delete_link(current_formatters, g_slist_last(current_formatters)); | ||||
| 				g_slist_foreach(current_formatters, _add_remaining_formatters, &r); | ||||
| 				a += tags[i].close_tag_length - 1; | ||||
| 				found = TRUE; | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if (found) | ||||
| 		{ | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		_str_append_char(&r, *a); | ||||
| 	} | ||||
|  | ||||
| 	_str_append_string(&r, ANSI_NORMAL); | ||||
|  | ||||
| 	*result = r; | ||||
|  | ||||
| 	return TRUE; | ||||
| } | ||||
|  | ||||
							
								
								
									
										20
									
								
								src/ansi.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/ansi.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| #ifndef __WMUD_CORE_ANSI_H__ | ||||
| #define __WMUD_CORE_ANSI_H__ | ||||
|  | ||||
| #define ANSI_CSI "\x1b[" | ||||
| #define ANSI_NORMAL ANSI_CSI "0m" | ||||
| #define ANSI_BOLD ANSI_CSI "1m" | ||||
| #define ANSI_UNDERLINE ANSI_CSI "4m" | ||||
| #define ANSI_COLOR_BLACK ANSI_CSI "30m" | ||||
| #define ANSI_COLOR_RED ANSI_CSI "31m" | ||||
| #define ANSI_COLOR_GREEN ANSI_CSI "32m" | ||||
| #define ANSI_COLOR_YELLOW ANSI_CSI "33m" | ||||
| #define ANSI_COLOR_BLUE ANSI_CSI "34m" | ||||
| #define ANSI_COLOR_MAGENTA ANSI_CSI "35m" | ||||
| #define ANSI_COLOR_CYAN ANSI_CSI "36m" | ||||
| #define ANSI_COLOR_WHITE ANSI_CSI "37m" | ||||
|  | ||||
| gboolean wmud_text_to_ansi(gchar *text, gchar **result); | ||||
|  | ||||
| #endif /* __WMUD_CODE__ANSI_H__ */ | ||||
|  | ||||
							
								
								
									
										42
									
								
								src/chat.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/chat.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| #include <glib.h> | ||||
|  | ||||
| #include "wmud.h" | ||||
| #include "logger.h" | ||||
|  | ||||
| gpointer | ||||
| wmud_chat_thread(gpointer data) | ||||
| { | ||||
| 	wMUDThreadData *thread_data = (wMUDThreadData *)data; | ||||
|  | ||||
| 	Context wmud_log_info("Initializing chat layer..."); | ||||
| 	/* g_main_context_get_thread_default() is only available since GLib 2.22; | ||||
| 	 * use g_main_context_new() otherwise | ||||
| 	 */ | ||||
| #if (((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION >= 22)) || (GLIB_MAJOR_VERSION > 2)) | ||||
| 	thread_data->main_context = g_main_context_get_thread_default(); | ||||
| #else | ||||
| 	thread_data->main_context = g_main_context_new(); | ||||
| #endif | ||||
| 	thread_data->main_loop = g_main_loop_new(thread_data->main_context, FALSE); | ||||
|  | ||||
| 	/* Do the real initialization work here */ | ||||
|  | ||||
| 	/* End of initialization */ | ||||
|  | ||||
| 	wmud_log_info("Chat layer initialized"); | ||||
|  | ||||
| 	Context; | ||||
| 	thread_data->running = TRUE; | ||||
| 	g_main_loop_run(thread_data->main_loop); | ||||
|  | ||||
| 	wmud_log_info("Chat layer shutting down"); | ||||
|  | ||||
| 	g_main_loop_unref(thread_data->main_loop); | ||||
| 	thread_data->main_loop = NULL; | ||||
|  | ||||
| 	thread_data->running = FALSE; | ||||
|  | ||||
| 	Context; | ||||
|  | ||||
| 	return NULL; | ||||
| } | ||||
							
								
								
									
										7
									
								
								src/chat.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/chat.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| #ifndef __WMUD_CORE_CHAT_H__ | ||||
| #define __WMUD_CORE_CHAT_H__ | ||||
|  | ||||
| gpointer wmud_chat_thread(gpointer data); | ||||
|  | ||||
| #endif /* __WMUD_CORE_CHAT_H__ */ | ||||
|  | ||||
							
								
								
									
										265
									
								
								src/commands.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										265
									
								
								src/commands.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,265 @@ | ||||
| #include <glib.h> | ||||
| #include <gnet.h> | ||||
|  | ||||
| #include <string.h> | ||||
|  | ||||
| #include "wmud.h" | ||||
| #include "logger.h" | ||||
| #include "networking.h" | ||||
| #include "sessions.h" | ||||
|  | ||||
| #include "wmud-session.h" | ||||
|  | ||||
| #define COMMAND_DELIMITERS " \t\n\r" | ||||
|  | ||||
| #define WMUD_COMMAND_ERROR g_quark_from_string("wMUDCommandError") | ||||
| enum { | ||||
| 	WMUD_COMMAND_ERROR_SUCCESS   /* Will never be used */ | ||||
| }; | ||||
|  | ||||
| /* Internal command callback function for prototypes and function headers. If | ||||
|  * you modify this, don't forget to modify the wMUDCommandCallback type! | ||||
|  */ | ||||
| #define WMUD_INTERNAL_COMMAND(x) gboolean x (wMUDSession *session, gchar **params, GError **error) | ||||
|  | ||||
| /* Internal command callback function type to be usd in the wMUDCommand struct. | ||||
|  * If you modify this, don't forget to modify the WMUD_INTERNAL_COMMAND(x) | ||||
|  * macro! | ||||
|  */ | ||||
| typedef gboolean (*wMUDCommandCallback)(wMUDSession *session, gchar **params, GError **error); | ||||
|  | ||||
| typedef struct _wMUDCommand | ||||
| { | ||||
| 	gchar *cmd; | ||||
| 	gchar *collate_key; | ||||
| 	gint min_params; | ||||
| 	gint max_params; | ||||
| 	wMUDCommandCallback callback; | ||||
| } wMUDCommand; | ||||
|  | ||||
| struct _wMUDSplitHelper | ||||
| { | ||||
| 	gchar **list; | ||||
| 	gint position; | ||||
| }; | ||||
|  | ||||
| WMUD_INTERNAL_COMMAND(_wmud_command_internal_quit); | ||||
|  | ||||
| static wMUDCommand _wmud_command_list[] = { | ||||
| 	{ "QUIT", NULL, 0, 0, _wmud_command_internal_quit }, | ||||
| 	{ NULL,   NULL, 0, 0, NULL } | ||||
| }; | ||||
|  | ||||
| WMUD_INTERNAL_COMMAND(_wmud_command_internal_quit) | ||||
| { | ||||
| 	wmud_log_debug("Here in the QUIT function"); | ||||
| 	wmud_finish_session(session, "Good bye"); | ||||
| 	return TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| _add_words(gpointer data, gpointer user_data) | ||||
| { | ||||
| 	struct _wMUDSplitHelper *split_data = (struct _wMUDSplitHelper *)user_data; | ||||
| 	gchar *word = (gchar *)data; | ||||
|  | ||||
| 	Context split_data->list[split_data->position] = word; | ||||
| 	split_data->position++; | ||||
| } | ||||
|  | ||||
| static void | ||||
| _free_words(gpointer data, gpointer user_data) | ||||
| { | ||||
| 	g_free(data); | ||||
| } | ||||
|  | ||||
| static gint | ||||
| _wmud_split_command(gchar *command, gchar ***list) | ||||
| { | ||||
| 	gchar *a; | ||||
| 	gint word_started_at = 0; | ||||
| 	gint apos_at = -1; | ||||
| 	gint quot_at = -1; | ||||
| 	gboolean was_in_word = FALSE; | ||||
| 	gboolean in_string = TRUE; | ||||
| 	GSList *word_list = NULL; | ||||
| 	gchar **ret; | ||||
| 	struct _wMUDSplitHelper split_data; | ||||
| 	gint word_count; | ||||
|  | ||||
| 	for (a = command; in_string; a++) | ||||
| 	{ | ||||
| 		if (*a == 0) | ||||
| 		{ | ||||
| 			in_string = FALSE; | ||||
| 		} | ||||
| 		if ( | ||||
| 				(*a == 0) | ||||
| 				|| ( | ||||
| 					(quot_at == -1) | ||||
| 					&& (*a == '\'') | ||||
| 				) | ||||
| 				|| ( | ||||
| 					(apos_at == -1) | ||||
| 					&& (*a == '"') | ||||
| 				) | ||||
| 				|| ( | ||||
| 					(apos_at != -1) | ||||
| 					&& (*a == '\'') | ||||
| 				) | ||||
| 				|| ( | ||||
| 					(quot_at != -1) | ||||
| 					&& (*a == '"') | ||||
| 				) | ||||
| 				|| ( | ||||
| 					(apos_at == -1) | ||||
| 					&& (quot_at == -1) | ||||
| 					&& strchr(COMMAND_DELIMITERS, *a) | ||||
| 				) | ||||
| 			) | ||||
| 		{ | ||||
| 			if (was_in_word) | ||||
| 			{ | ||||
| 				was_in_word = FALSE; | ||||
| 				word_list = g_slist_append(word_list, g_strndup((command + word_started_at), (a - command) - word_started_at)); | ||||
| 				word_started_at = (a - command); | ||||
| 			} | ||||
| 			if ((apos_at == -1) && (*a == '"')) | ||||
| 			{ | ||||
| 				if (quot_at == -1) | ||||
| 				{ | ||||
| 					quot_at = (a - command) - 1; | ||||
| 					if (quot_at == -1) | ||||
| 					{ | ||||
| 						quot_at = 0; | ||||
| 					} | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					quot_at = -1; | ||||
| 				} | ||||
| 			} | ||||
| 			if ((quot_at == -1) && (*a == '\'')) | ||||
| 			{ | ||||
| 				if (apos_at == -1) | ||||
| 				{ | ||||
| 					apos_at = (a - command) - 1; | ||||
| 					if (apos_at == -1) | ||||
| 					{ | ||||
| 						apos_at = 0; | ||||
| 					} | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					apos_at = -1; | ||||
| 				} | ||||
| 			} | ||||
| 			word_started_at++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		was_in_word = TRUE; | ||||
| 	} | ||||
| 	 | ||||
| 	if ((quot_at != -1) || (apos_at != -1)) | ||||
| 	{ | ||||
| 		wmud_log_debug("Got illegal string: %s", command); | ||||
|  | ||||
| 		g_slist_foreach(word_list, _free_words, NULL); | ||||
| 		g_slist_free(word_list); | ||||
|  | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	word_count = g_slist_length(word_list); | ||||
| 	Context ret = g_new0(gchar *, word_count + 1); | ||||
|  | ||||
| 	split_data.list = ret; | ||||
| 	split_data.position = 0; | ||||
|  | ||||
| 	Context g_slist_foreach(word_list, _add_words, &split_data); | ||||
| 	g_slist_free(word_list); | ||||
|  | ||||
| 	if (list != NULL) | ||||
| 	{ | ||||
| 		Context *list = ret; | ||||
| 	} | ||||
|  | ||||
| 	return word_count; | ||||
| } | ||||
|  | ||||
| void | ||||
| wmud_process_command(GConn *connection, gchar *command) | ||||
| { | ||||
| 	gchar **command_parts = NULL, | ||||
| 		  *command_casefold, | ||||
| 		  *command_key; | ||||
| 	gint word_count; | ||||
| 	wMUDCommand *command_rec; | ||||
| 	gboolean command_found = FALSE; | ||||
| 	wMUDSession *session; | ||||
|  | ||||
| 	session = wmud_session_for_connection(connection); | ||||
|  | ||||
| 	if (session == NULL) | ||||
| 	{ | ||||
| 		wmud_log_error("Processing command for a non-existant session!"); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	Context; | ||||
| 	wmud_log_debug("Processing command %s", command); | ||||
|  | ||||
| 	Context word_count = _wmud_split_command(command, &command_parts); | ||||
|  | ||||
| 	if (word_count == -1) | ||||
| 	{ | ||||
| 		Context wmud_connection_send(connection, "Illegal command. Maybe you forgot a closing apostroph or quote?"); | ||||
| 		Context return; | ||||
| 	} | ||||
|  | ||||
| 	if (word_count == 0) | ||||
| 	{ | ||||
| 		wmud_log_debug("Got an empty line"); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	command_casefold = g_utf8_casefold(command_parts[0], -1); | ||||
| 	command_key = g_utf8_collate_key(command_casefold, -1); | ||||
| 	g_free(command_casefold); | ||||
| 	for (command_rec = _wmud_command_list; command_rec->cmd; command_rec++) | ||||
| 	{ | ||||
| 		if (command_rec->collate_key == NULL) | ||||
| 		{ | ||||
| 			gchar *temp; | ||||
|  | ||||
| 			temp = g_utf8_casefold(command_rec->cmd, -1); | ||||
| 			command_rec->collate_key = g_utf8_collate_key(temp, -1); | ||||
| 			g_free(temp); | ||||
| 		} | ||||
|  | ||||
| 		if (strcmp(command_key, command_rec->collate_key) == 0) | ||||
| 		{ | ||||
| 			gint param_count = g_strv_length(command_parts) - 1; | ||||
| 			GError *error = NULL; | ||||
| 			command_found = TRUE; | ||||
|  | ||||
| 			if ((param_count < command_rec->min_params) || (param_count > command_rec->max_params)) | ||||
| 			{ | ||||
| 				Context wmud_connection_send(connection, "Wrong number of parameters. Maybe you should try HELP %s", command_rec->cmd); | ||||
| 			} | ||||
| 			wmud_log_debug("Executing command %s, having %d parameters", command_rec->cmd, param_count); | ||||
| 			(command_rec->callback)(session, command_parts + 1, &error); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	g_free(command_key); | ||||
|  | ||||
| 	if (!command_found) | ||||
| 	{ | ||||
| 		/* TODO: command prediction (Maybe you wanted to type...) */ | ||||
| 		Context wmud_connection_send(connection, "Unknown command."); | ||||
| 	} | ||||
|  | ||||
| 	Context g_strfreev(command_parts); | ||||
| } | ||||
|  | ||||
							
								
								
									
										9
									
								
								src/commands.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/commands.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| #ifndef __WMUD_CORE_COMMANDS_H | ||||
| #define __WMUD_CORE_COMMANDS_H | ||||
|  | ||||
| #include <gnet.h> | ||||
|  | ||||
| void wmud_process_command(GConn *connection, gchar *command); | ||||
|  | ||||
| #endif /* __WMUD_CORE_COMMANDS_H */ | ||||
|  | ||||
							
								
								
									
										75
									
								
								src/configfile-module.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/configfile-module.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| #ifndef __WMUD_MODULE_CONFIGFILE_H__ | ||||
| #define __WMUD_MODULE_CONFIGFILE_H__ | ||||
|  | ||||
| #include "wmud-session.h" | ||||
|  | ||||
| typedef enum { | ||||
| 	WMUD_CONF_LOG_NONE, | ||||
| 	WMUD_CONF_LOG_SYSLOG, | ||||
| 	WMUD_CONF_LOG_FILE, | ||||
| 	WMUD_CONF_LOG_CONSOLE | ||||
| } wMUDConfigurationLogging; | ||||
|  | ||||
| typedef enum { | ||||
| 	WMUD_CONF_DAEMONIZE_YES, | ||||
| 	WMUD_CONF_DAEMONIZE_NO, | ||||
| 	WMUD_CONF_DAEMONIZE_FORCE | ||||
| } wMUDConfigurationDaemonize; | ||||
|  | ||||
| typedef struct { | ||||
| 	/* A GSList of _wMUDConfigurationInterfaces */ | ||||
| 	GSList *interfaces; | ||||
|  | ||||
| 	wMUDConfigurationLogging log_dest; | ||||
| 	gchar *logfile; | ||||
| 	gboolean log_found; | ||||
|  | ||||
| 	wMUDConfigurationLogging debug_log_dest; | ||||
| 	gchar *debug_logfile; | ||||
| 	gboolean debug_log_found; | ||||
|  | ||||
| 	wMUDConfigurationLogging info_log_dest; | ||||
| 	gchar *info_logfile; | ||||
| 	gboolean info_log_found; | ||||
|  | ||||
| 	wMUDConfigurationLogging warning_log_dest; | ||||
| 	gchar *warning_logfile; | ||||
| 	gboolean warning_log_found; | ||||
|  | ||||
| 	wMUDConfigurationLogging error_log_dest; | ||||
| 	gchar *error_logfile; | ||||
| 	gboolean error_log_found; | ||||
|  | ||||
| 	wMUDConfigurationDaemonize daemonize; | ||||
|  | ||||
| 	gboolean chat_enabled; | ||||
| 	gboolean dbus_enabled; | ||||
|  | ||||
| 	gchar *modules_dir; | ||||
|  | ||||
| 	gchar *statesave_module; | ||||
| 	gchar **protocol_modules; | ||||
|  | ||||
| 	GSList *statesave_parameters; | ||||
| 	GSList *protocol_parameters; | ||||
| } wMUDConfiguration; | ||||
|  | ||||
| typedef struct { | ||||
| 	wMUDSessionType type; | ||||
| 	gchar *name; | ||||
| 	GInetAddr *inetaddr; | ||||
| 	guint timeout; | ||||
| } wMUDConfigurationInterface; | ||||
|  | ||||
| typedef struct { | ||||
| 	gchar *name; | ||||
| 	GSList *datalist; | ||||
| } wMUDConfigurationGroup; | ||||
|  | ||||
| typedef struct { | ||||
| 	gchar *key; | ||||
| 	gchar *value; | ||||
| } wMUDConfigurationValue; | ||||
|  | ||||
| #endif /* __WMUD_MODULE_CONFIGFILE_H__ */ | ||||
|  | ||||
							
								
								
									
										901
									
								
								src/configfile.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										901
									
								
								src/configfile.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,901 @@ | ||||
| #include <glib.h> | ||||
| #include <gnet.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include "wmud.h" | ||||
| #include "configfile.h" | ||||
| #include "logger.h" | ||||
|  | ||||
| struct _wMUDIfaceFinder { | ||||
| 	wMUDSessionType type; | ||||
| 	gchar *name; | ||||
| }; | ||||
|  | ||||
| static gint | ||||
| _wmud_find_keyed_member(gconstpointer this_group, gconstpointer group_to_find) | ||||
| { | ||||
| 	wMUDConfigurationGroup *group_data = (wMUDConfigurationGroup *)this_group; | ||||
| 	gchar *name = (gchar *)group_to_find; | ||||
|  | ||||
| 	return g_utf8_collate(group_data->name, name); | ||||
| } | ||||
|  | ||||
| static gint | ||||
| _wmud_find_iface(gconstpointer iface, gconstpointer iffinder) | ||||
| { | ||||
| 	wMUDConfigurationInterface *interface = (wMUDConfigurationInterface *)iface; | ||||
| 	gchar *name_to_find = ((struct _wMUDIfaceFinder *)iffinder)->name; | ||||
| 	wMUDSessionType type = ((struct _wMUDIfaceFinder *)iffinder)->type; | ||||
|  | ||||
| 	return ((g_utf8_collate(interface->name, name_to_find) == 0) && (interface->type == type)) ? 0 : 1; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| _wmud_config_process_value(wMUDConfiguration *conf, gchar *group, gchar *key, gchar *value) | ||||
| { | ||||
| 	GPatternSpec *group_ptn; | ||||
|  | ||||
| 	if (g_utf8_collate("general", group) == 0) | ||||
| 	{ | ||||
| 		if ( | ||||
| 				(g_utf8_collate("log", key) == 0) | ||||
| 				|| (g_utf8_collate("debug log", key) == 0) | ||||
| 				|| (g_utf8_collate("info log", key) == 0) | ||||
| 				|| (g_utf8_collate("warning log", key) == 0) | ||||
| 				|| (g_utf8_collate("error log", key) == 0) | ||||
| 		) | ||||
| 		{ | ||||
| 			if (g_utf8_collate("none", value) == 0) | ||||
| 			{ | ||||
| 				if (g_utf8_collate("log", key) == 0) | ||||
| 				{ | ||||
| 					conf->log_found = TRUE; | ||||
| 					conf->log_dest = WMUD_CONF_LOG_NONE; | ||||
| 					if (conf->logfile) | ||||
| 					{ | ||||
| 						g_free(conf->logfile); | ||||
| 						conf->logfile = NULL; | ||||
| 					} | ||||
| 					return TRUE; | ||||
| 				} | ||||
| 				else if (g_utf8_collate("debug log", key) == 0) | ||||
| 				{ | ||||
| 					conf->debug_log_found = TRUE; | ||||
| 					conf->debug_log_dest = WMUD_CONF_LOG_NONE; | ||||
| 					if (conf->debug_logfile) | ||||
| 					{ | ||||
| 						g_free(conf->debug_logfile); | ||||
| 						conf->debug_logfile = NULL; | ||||
| 					} | ||||
| 					return TRUE; | ||||
| 				} | ||||
| 				else if (g_utf8_collate("info log", key) == 0) | ||||
| 				{ | ||||
| 					conf->info_log_found = TRUE; | ||||
| 					conf->info_log_dest = WMUD_CONF_LOG_NONE; | ||||
| 					if (conf->info_logfile) | ||||
| 					{ | ||||
| 						g_free(conf->info_logfile); | ||||
| 						conf->info_logfile = NULL; | ||||
| 					} | ||||
| 					return TRUE; | ||||
| 				} | ||||
| 				else if (g_utf8_collate("warning log", key) == 0) | ||||
| 				{ | ||||
| 					conf->warning_log_found = TRUE; | ||||
| 					conf->warning_log_dest = WMUD_CONF_LOG_NONE; | ||||
| 					if (conf->warning_logfile) | ||||
| 					{ | ||||
| 						g_free(conf->warning_logfile); | ||||
| 						conf->warning_logfile = NULL; | ||||
| 					} | ||||
| 					return TRUE; | ||||
| 				} | ||||
| 				else if (g_utf8_collate("error log", key) == 0) | ||||
| 				{ | ||||
| 					conf->error_log_found = TRUE; | ||||
| 					conf->error_log_dest = WMUD_CONF_LOG_NONE; | ||||
| 					if (conf->error_logfile) | ||||
| 					{ | ||||
| 						g_free(conf->error_logfile); | ||||
| 						conf->error_logfile = NULL; | ||||
| 					} | ||||
| 					return TRUE; | ||||
| 				} | ||||
| 			} | ||||
| 			if (strncmp("file:", value, 5) == 0) | ||||
| 			{ | ||||
| 				if (g_utf8_collate("log", key) == 0) | ||||
| 				{ | ||||
| 					gchar *temp_file; | ||||
| 					wMUDConfigurationLogging temp_logging; | ||||
| 					gboolean temp_found; | ||||
|  | ||||
| 					temp_logging = conf->log_dest; | ||||
| 					temp_file = conf->logfile; | ||||
| 					temp_found = conf->log_found; | ||||
|  | ||||
| 					conf->logfile = g_strdup(value + 5); | ||||
| 					if (!*(conf->logfile)) | ||||
| 					{ | ||||
| 						wmud_log_error("Log file name must contain a string for %s/%s!", group, key); | ||||
| 						conf->logfile = temp_file; | ||||
| 						return FALSE; | ||||
| 					} | ||||
| 					if (temp_file) | ||||
| 					{ | ||||
| 						g_free(temp_file); | ||||
| 					} | ||||
| 					conf->log_dest = WMUD_CONF_LOG_FILE; | ||||
| 					conf->log_found = TRUE; | ||||
| 					return TRUE; | ||||
| 				} | ||||
| 				else if (g_utf8_collate("debug log", key) == 0) | ||||
| 				{ | ||||
| 					gchar *temp_file; | ||||
| 					wMUDConfigurationLogging temp_logging; | ||||
| 					gboolean temp_found; | ||||
|  | ||||
| 					temp_logging = conf->debug_log_dest; | ||||
| 					temp_file = conf->debug_logfile; | ||||
| 					temp_found = conf->debug_log_found; | ||||
|  | ||||
| 					conf->debug_logfile = g_strdup(value + 5); | ||||
| 					if (!*(conf->debug_logfile)) | ||||
| 					{ | ||||
| 						wmud_log_error("Debug log file name must contain a string for %s/%s!", group, key); | ||||
| 						conf->debug_logfile = temp_file; | ||||
| 						return FALSE; | ||||
| 					} | ||||
| 					if (temp_file) | ||||
| 					{ | ||||
| 						g_free(temp_file); | ||||
| 					} | ||||
| 					conf->debug_log_dest = WMUD_CONF_LOG_FILE; | ||||
| 					conf->debug_log_found = TRUE; | ||||
| 					return TRUE; | ||||
| 				} | ||||
| 				else if (g_utf8_collate("info log", key) == 0) | ||||
| 				{ | ||||
| 					gchar *temp_file; | ||||
| 					wMUDConfigurationLogging temp_logging; | ||||
| 					gboolean temp_found; | ||||
|  | ||||
| 					temp_logging = conf->info_log_dest; | ||||
| 					temp_file = conf->info_logfile; | ||||
| 					temp_found = conf->info_log_found; | ||||
|  | ||||
| 					conf->info_logfile = g_strdup(value + 5); | ||||
| 					if (!*(conf->info_logfile)) | ||||
| 					{ | ||||
| 						wmud_log_error("Info log file name must contain a string for %s/%s!", group, key); | ||||
| 						conf->info_log_dest = temp_logging; | ||||
| 						conf->info_logfile = temp_file; | ||||
| 						conf->info_log_found = temp_found; | ||||
| 						return FALSE; | ||||
| 					} | ||||
| 					if (temp_file) | ||||
| 					{ | ||||
| 						g_free(temp_file); | ||||
| 					} | ||||
| 					conf->info_log_dest = WMUD_CONF_LOG_FILE; | ||||
| 					conf->info_log_found = TRUE; | ||||
| 					return TRUE; | ||||
| 				} | ||||
| 				else if (g_utf8_collate("warning log", key) == 0) | ||||
| 				{ | ||||
| 					gchar *temp_file; | ||||
| 					wMUDConfigurationLogging temp_logging; | ||||
| 					gboolean temp_found; | ||||
|  | ||||
| 					temp_logging = conf->warning_log_dest; | ||||
| 					temp_file = conf->warning_logfile; | ||||
| 					temp_found = conf->warning_log_found; | ||||
|  | ||||
| 					conf->warning_logfile = g_strdup(value + 5); | ||||
| 					if (!*(conf->warning_logfile)) | ||||
| 					{ | ||||
| 						wmud_log_error("Warning log file name must contain a string for %s/%s!", group, key); | ||||
| 						conf->warning_logfile = temp_file; | ||||
| 						return FALSE; | ||||
| 					} | ||||
| 					if (temp_file) | ||||
| 					{ | ||||
| 						g_free(temp_file); | ||||
| 					} | ||||
| 					conf->warning_log_dest = WMUD_CONF_LOG_FILE; | ||||
| 					conf->warning_log_found = TRUE; | ||||
| 					return TRUE; | ||||
| 				} | ||||
| 				else if (g_utf8_collate("error log", key) == 0) | ||||
| 				{ | ||||
| 					gchar *temp_file; | ||||
| 					wMUDConfigurationLogging temp_logging; | ||||
| 					gboolean temp_found; | ||||
|  | ||||
| 					temp_logging = conf->error_log_dest; | ||||
| 					temp_file = conf->error_logfile; | ||||
| 					temp_found = conf->error_log_found; | ||||
|  | ||||
| 					conf->error_logfile = g_strdup(value + 5); | ||||
| 					if (!*(conf->error_logfile)) | ||||
| 					{ | ||||
| 						wmud_log_error("Error log file name must contain a string for %s/%s!", group, key); | ||||
| 						conf->error_logfile = temp_file; | ||||
| 						return FALSE; | ||||
| 					} | ||||
| 					if (temp_file) | ||||
| 					{ | ||||
| 						g_free(temp_file); | ||||
| 					} | ||||
| 					conf->error_log_dest = WMUD_CONF_LOG_FILE; | ||||
| 					conf->error_log_found = TRUE; | ||||
| 					return TRUE; | ||||
| 				} | ||||
| 			} | ||||
| 			if ( | ||||
| 					(g_utf8_collate("syslog", value) == 0) | ||||
| 					|| ( | ||||
| 						(conf->daemonize == WMUD_CONF_DAEMONIZE_FORCE) | ||||
| 						&& (g_utf8_collate("console", value) == 0) | ||||
| 					) | ||||
| 			) | ||||
| 			{ | ||||
| 				if (g_utf8_collate("log", key) == 0) | ||||
| 				{ | ||||
| 					conf->log_dest = WMUD_CONF_LOG_SYSLOG; | ||||
| 					conf->log_found = TRUE; | ||||
| 					if (conf->logfile) | ||||
| 					{ | ||||
| 						g_free(conf->logfile); | ||||
| 						conf->logfile = NULL; | ||||
| 					} | ||||
| 					return TRUE; | ||||
| 				} | ||||
| 				else if (g_utf8_collate("debug log", key) == 0) | ||||
| 				{ | ||||
| 					conf->debug_log_dest = WMUD_CONF_LOG_SYSLOG; | ||||
| 					conf->debug_log_found = TRUE; | ||||
| 					if (conf->debug_logfile) | ||||
| 					{ | ||||
| 						g_free(conf->debug_logfile); | ||||
| 						conf->debug_logfile = NULL; | ||||
| 					} | ||||
| 					return TRUE; | ||||
| 				} | ||||
| 				else if (g_utf8_collate("info log", key) == 0) | ||||
| 				{ | ||||
| 					conf->info_log_dest = WMUD_CONF_LOG_SYSLOG; | ||||
| 					conf->info_log_found = TRUE; | ||||
| 					if (conf->info_logfile) | ||||
| 					{ | ||||
| 						g_free(conf->info_logfile); | ||||
| 						conf->info_logfile = NULL; | ||||
| 					} | ||||
| 					return TRUE; | ||||
| 				} | ||||
| 				else if (g_utf8_collate("warning log", key) == 0) | ||||
| 				{ | ||||
| 					conf->warning_log_dest = WMUD_CONF_LOG_SYSLOG; | ||||
| 					conf->warning_log_found = TRUE; | ||||
| 					if (conf->warning_logfile) | ||||
| 					{ | ||||
| 						g_free(conf->warning_logfile); | ||||
| 						conf->warning_logfile = NULL; | ||||
| 					} | ||||
| 					return TRUE; | ||||
| 				} | ||||
| 				else if (g_utf8_collate("error log", key) == 0) | ||||
| 				{ | ||||
| 					conf->error_log_dest = WMUD_CONF_LOG_SYSLOG; | ||||
| 					conf->error_log_found = TRUE; | ||||
| 					if (conf->error_logfile) | ||||
| 					{ | ||||
| 						g_free(conf->error_logfile); | ||||
| 						conf->error_logfile = NULL; | ||||
| 					} | ||||
| 					return TRUE; | ||||
| 				} | ||||
| 			} | ||||
| 			if ((g_utf8_collate("console", value) == 0) && (conf->daemonize != WMUD_CONF_DAEMONIZE_FORCE)) | ||||
| 			{ | ||||
| 				if (g_utf8_collate("log", key) == 0) | ||||
| 				{ | ||||
| 					conf->log_dest = WMUD_CONF_LOG_CONSOLE; | ||||
| 					conf->log_found = TRUE; | ||||
| 					if (conf->logfile) | ||||
| 					{ | ||||
| 						g_free(conf->logfile); | ||||
| 						conf->logfile = NULL; | ||||
| 					} | ||||
| 					return TRUE; | ||||
| 				} | ||||
| 				else if (g_utf8_collate("debug log", key) == 0) | ||||
| 				{ | ||||
| 					conf->debug_log_dest = WMUD_CONF_LOG_CONSOLE; | ||||
| 					conf->debug_log_found = TRUE; | ||||
| 					if (conf->debug_logfile) | ||||
| 					{ | ||||
| 						g_free(conf->debug_logfile); | ||||
| 						conf->debug_logfile = NULL; | ||||
| 					} | ||||
| 					return TRUE; | ||||
| 				} | ||||
| 				else if (g_utf8_collate("info log", key) == 0) | ||||
| 				{ | ||||
| 					conf->info_log_dest = WMUD_CONF_LOG_CONSOLE; | ||||
| 					conf->info_log_found = TRUE; | ||||
| 					if (conf->info_logfile) | ||||
| 					{ | ||||
| 						g_free(conf->info_logfile); | ||||
| 						conf->info_logfile = NULL; | ||||
| 					} | ||||
| 					return TRUE; | ||||
| 				} | ||||
| 				else if (g_utf8_collate("warning log", key) == 0) | ||||
| 				{ | ||||
| 					conf->warning_log_dest = WMUD_CONF_LOG_CONSOLE; | ||||
| 					conf->warning_log_found = TRUE; | ||||
| 					if (conf->warning_logfile) | ||||
| 					{ | ||||
| 						g_free(conf->warning_logfile); | ||||
| 						conf->warning_logfile = NULL; | ||||
| 					} | ||||
| 					return TRUE; | ||||
| 				} | ||||
| 				else if (g_utf8_collate("error log", key) == 0) | ||||
| 				{ | ||||
| 					conf->error_log_dest = WMUD_CONF_LOG_CONSOLE; | ||||
| 					conf->error_log_found = TRUE; | ||||
| 					if (conf->error_logfile) | ||||
| 					{ | ||||
| 						g_free(conf->error_logfile); | ||||
| 						conf->error_logfile = NULL; | ||||
| 					} | ||||
| 					return TRUE; | ||||
| 				} | ||||
| 			} | ||||
| 			wmud_log_error("Found the log option with an unknown value of %s", value); | ||||
| 			return FALSE; | ||||
| 		} | ||||
|  | ||||
| 		if (g_utf8_collate("daemonize", key) == 0) | ||||
| 		{ | ||||
| 			if (g_utf8_collate("yes", value) == 0) | ||||
| 			{ | ||||
| 				conf->daemonize = WMUD_CONF_DAEMONIZE_YES; | ||||
| 				return TRUE; | ||||
| 			} | ||||
| 			else if (g_utf8_collate("no", value) == 0) | ||||
| 			{ | ||||
| 				conf->daemonize = WMUD_CONF_DAEMONIZE_NO; | ||||
| 				return TRUE; | ||||
| 			} | ||||
| 			else if (g_utf8_collate("force", value) == 0) | ||||
| 			{ | ||||
| 				conf->daemonize = WMUD_CONF_DAEMONIZE_FORCE; | ||||
| 				return TRUE; | ||||
| 			} | ||||
| 			wmud_log_error("Daemonize must have the values yes, no or force"); | ||||
| 			return FALSE; | ||||
| 		} | ||||
|  | ||||
| 		if (g_utf8_collate("chat", key) == 0) | ||||
| 		{ | ||||
| 			if (g_utf8_collate("yes", value) == 0) | ||||
| 			{ | ||||
| 				conf->chat_enabled = TRUE; | ||||
| 				return TRUE; | ||||
| 			} | ||||
| 			else if (g_utf8_collate("no", value) == 0) | ||||
| 			{ | ||||
| 				conf->chat_enabled = FALSE; | ||||
| 				return TRUE; | ||||
| 			} | ||||
| 			wmud_log_error("Chat must have the value yes or no"); | ||||
| 			return FALSE; | ||||
| 		} | ||||
|  | ||||
| 		if (g_utf8_collate("dbus", key) == 0) | ||||
| 		{ | ||||
| 			if (g_utf8_collate("yes", value) == 0) | ||||
| 			{ | ||||
| 				conf->dbus_enabled = TRUE; | ||||
| 				return TRUE; | ||||
| 			} | ||||
| 			else if (g_utf8_collate("no", value) == 0) | ||||
| 			{ | ||||
| 				conf->dbus_enabled = TRUE; | ||||
| 				return TRUE; | ||||
| 			} | ||||
| 			wmud_log_error("DBus must have the value yes or no"); | ||||
| 			return FALSE; | ||||
| 		} | ||||
|  | ||||
| 		wmud_log_error("Unknown key (%s) found in configuration file in group [%s]", key, group); | ||||
| 		return FALSE; | ||||
| 	} | ||||
|  | ||||
| 	if (g_utf8_collate("modules", group) == 0) | ||||
| 	{ | ||||
| 		if (g_utf8_collate("modules dir", key) == 0) | ||||
| 		{ | ||||
| 			if (conf->modules_dir) | ||||
| 			{ | ||||
| 				g_free(conf->modules_dir); | ||||
| 			} | ||||
| 			conf->modules_dir = g_strdup(value); | ||||
| 			return TRUE; | ||||
| 		} | ||||
|  | ||||
| 		if (g_utf8_collate("statesave", key) == 0) | ||||
| 		{ | ||||
| 			if (conf->statesave_module) | ||||
| 			{ | ||||
| 				g_free(conf->statesave_module); | ||||
| 			} | ||||
| 			conf->statesave_module = g_strdup(value); | ||||
| 			return TRUE; | ||||
| 		} | ||||
|  | ||||
| 		if (g_utf8_collate("protocol", key) == 0) | ||||
| 		{ | ||||
| 			if (conf->protocol_modules) | ||||
| 			{ | ||||
| 				g_strfreev(conf->protocol_modules); | ||||
| 			} | ||||
|  | ||||
| 			conf->protocol_modules = g_strsplit(value, ":", 0); | ||||
| 			return TRUE; | ||||
| 		} | ||||
|  | ||||
| 		wmud_log_error("Unknown key (%s) found in configuration file in group [%s]", key, group); | ||||
| 		return FALSE; | ||||
| 	} | ||||
|  | ||||
| 	group_ptn = g_pattern_spec_new("statesave *"); | ||||
| 	if (g_pattern_match(group_ptn, strlen(group), group, NULL)) | ||||
| 	{ | ||||
| 		GSList *statesave_member; | ||||
| 		wMUDConfigurationGroup *conf_group; | ||||
| 		wMUDConfigurationValue *conf_data; | ||||
|  | ||||
| 		statesave_member = g_slist_find_custom(conf->statesave_parameters, group + 10, _wmud_find_keyed_member); | ||||
| 		if (statesave_member == NULL) | ||||
| 		{ | ||||
| 			conf_group = g_new0(wMUDConfigurationGroup, 1); | ||||
| 			conf_group->name = g_strdup(group + 10); | ||||
| 			conf_group->datalist = NULL; | ||||
| 			conf->statesave_parameters = g_slist_append(conf->statesave_parameters, conf_group); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			conf_group = (wMUDConfigurationGroup *)(statesave_member->data); | ||||
| 		} | ||||
|  | ||||
| 		conf_data = g_new0(wMUDConfigurationValue, 1); | ||||
| 		conf_data->key = g_strdup(key); | ||||
| 		conf_data->value = g_strdup(value); | ||||
| 		conf_group->datalist = g_slist_append(conf_group->datalist, conf_data); | ||||
|  | ||||
| 		return TRUE; | ||||
| 	} | ||||
| 	g_pattern_spec_free(group_ptn); | ||||
|  | ||||
| 	group_ptn = g_pattern_spec_new("protocol * *"); | ||||
| 	if (g_pattern_match(group_ptn, strlen(group), group, NULL)) | ||||
| 	{ | ||||
| 		GSList *protocol_member; | ||||
| 		wMUDConfigurationGroup *conf_group; | ||||
| 		wMUDConfigurationValue *conf_data; | ||||
|  | ||||
| 		protocol_member = g_slist_find_custom(conf->protocol_parameters, group + 10, _wmud_find_keyed_member); | ||||
| 		if (protocol_member == NULL) | ||||
| 		{ | ||||
| 			conf_group = g_new0(wMUDConfigurationGroup, 1); | ||||
| 			conf_group->name = g_strdup(group + 10); | ||||
| 			conf_group->datalist = NULL; | ||||
| 			conf->protocol_parameters = g_slist_append(conf->protocol_parameters, conf_group); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			conf_group = (wMUDConfigurationGroup *)(protocol_member->data); | ||||
| 		} | ||||
|  | ||||
| 		conf_data = g_new0(wMUDConfigurationValue, 1); | ||||
| 		conf_data->key = g_strdup(key); | ||||
| 		conf_data->value = g_strdup(value); | ||||
| 		conf_group->datalist = g_slist_append(conf_group->datalist, conf_data); | ||||
|  | ||||
| 		return TRUE; | ||||
| 	} | ||||
| 	g_pattern_spec_free(group_ptn); | ||||
|  | ||||
| 	group_ptn = g_pattern_spec_new("irc *"); | ||||
| 	if (g_pattern_match(group_ptn, strlen(group), group, NULL)) | ||||
| 	{ | ||||
| 		GSList *temp; | ||||
| 		wMUDConfigurationInterface *interface; | ||||
| 		gchar *iface_name; | ||||
| 		struct _wMUDIfaceFinder *finder; | ||||
|  | ||||
| 		finder = g_new0(struct _wMUDIfaceFinder, 1); | ||||
|  | ||||
| 		finder->type = WMUD_SESSION_TYPE_IRC; | ||||
| 		finder->name = iface_name = g_utf8_offset_to_pointer(group, 4); | ||||
| 		Context; | ||||
| 		temp = g_slist_find_custom(conf->interfaces, finder, _wmud_find_iface); | ||||
| 		Context; | ||||
| 		g_free(finder); | ||||
|  | ||||
| 		if (temp == NULL) | ||||
| 		{ | ||||
| 			Context; | ||||
| 			interface = (wMUDConfigurationInterface *)g_new0(wMUDConfigurationInterface, 1); | ||||
| 			interface->name = g_strdup(iface_name); | ||||
| 			interface->type = WMUD_SESSION_TYPE_IRC; | ||||
| 			conf->interfaces = g_slist_append(conf->interfaces, interface); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			Context; | ||||
| 			interface = (wMUDConfigurationInterface *)(temp->data); | ||||
| 		} | ||||
|  | ||||
| 		if (g_utf8_collate("port", key) == 0) | ||||
| 		{ | ||||
| 			guint64 portnumber; | ||||
| 			gchar *endptr; | ||||
|  | ||||
| 			portnumber = g_ascii_strtoull(value, &endptr, 10); | ||||
|  | ||||
| 			if ((endptr != NULL) && (*endptr != 0)) | ||||
| 			{ | ||||
| 				wmud_log_error("Error in configuration file. Value of port can only contain numbers in group [%s]!", group); | ||||
| 			} | ||||
|  | ||||
| 			if (interface->inetaddr == NULL) | ||||
| 			{ | ||||
| 				interface->inetaddr = gnet_inetaddr_new("0.0.0.0", portnumber); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				gnet_inetaddr_set_port(interface->inetaddr, (gint)portnumber); | ||||
| 			} | ||||
|  | ||||
| 			g_pattern_spec_free(group_ptn); | ||||
| 			return TRUE; | ||||
| 		} | ||||
| 		wmud_log_error("Unknown key (%s) found in configuration file in group [%s]", key, group); | ||||
| 		g_pattern_spec_free(group_ptn); | ||||
| 		return FALSE; | ||||
| 	} | ||||
| 	g_pattern_spec_free(group_ptn); | ||||
|  | ||||
| 	wmud_log_error("Unknown group (%s) found in configuration file", group); | ||||
| 	return FALSE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| _wmud_configuration_free_interface(gpointer data, gpointer user_data) | ||||
| { | ||||
| 	wMUDConfigurationInterface *iface = (wMUDConfigurationInterface *)data; | ||||
|  | ||||
| 	if (iface->name) | ||||
| 	{ | ||||
| 		g_free(iface->name); | ||||
| 	} | ||||
| 	if (iface->inetaddr) | ||||
| 	{ | ||||
| 		gnet_inetaddr_unref(iface->inetaddr); | ||||
| 	} | ||||
| 	g_free(data); | ||||
| } | ||||
|  | ||||
| static void | ||||
| _wmud_configuration_free_value(gpointer data, gpointer user_data) | ||||
| { | ||||
| 	wMUDConfigurationValue *v = (wMUDConfigurationValue *)data; | ||||
|  | ||||
| 	if (v->key) | ||||
| 	{ | ||||
| 		g_free(v->key); | ||||
| 	} | ||||
| 	if (v->value) | ||||
| 	{ | ||||
| 		g_free(v->value); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void | ||||
| _wmud_configuration_free_parameters(gpointer data, gpointer user_data) | ||||
| { | ||||
| 	wMUDConfigurationGroup *group = (wMUDConfigurationGroup *)data; | ||||
|  | ||||
| 	g_slist_foreach(group->datalist, _wmud_configuration_free_value, NULL); | ||||
| 	g_slist_free(group->datalist); | ||||
| 	if (group->name) | ||||
| 	{ | ||||
| 		g_free(group->name); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void | ||||
| wmud_configuration_free(wMUDConfiguration **configuration) | ||||
| { | ||||
| 	g_slist_foreach((*configuration)->interfaces, _wmud_configuration_free_interface, NULL); | ||||
| 	g_slist_free((*configuration)->interfaces); | ||||
|  | ||||
| 	g_slist_foreach((*configuration)->statesave_parameters, _wmud_configuration_free_parameters, NULL); | ||||
| 	g_slist_free((*configuration)->statesave_parameters); | ||||
|  | ||||
| 	g_slist_foreach((*configuration)->protocol_parameters, _wmud_configuration_free_parameters, NULL); | ||||
| 	g_slist_free((*configuration)->protocol_parameters); | ||||
|  | ||||
| 	if ((*configuration)->logfile) | ||||
| 	{ | ||||
| 		g_free((*configuration)->logfile); | ||||
| 	} | ||||
| 	if ((*configuration)->debug_logfile) | ||||
| 	{ | ||||
| 		g_free((*configuration)->debug_logfile); | ||||
| 	} | ||||
| 	if ((*configuration)->info_logfile) | ||||
| 	{ | ||||
| 		g_free((*configuration)->info_logfile); | ||||
| 	} | ||||
| 	if ((*configuration)->warning_logfile) | ||||
| 	{ | ||||
| 		g_free((*configuration)->warning_logfile); | ||||
| 	} | ||||
| 	if ((*configuration)->error_logfile) | ||||
| 	{ | ||||
| 		g_free((*configuration)->error_logfile); | ||||
| 	} | ||||
|  | ||||
| 	if ((*configuration)->modules_dir) | ||||
| 	{ | ||||
| 		g_free((*configuration)->modules_dir); | ||||
| 	} | ||||
|  | ||||
| 	if ((*configuration)->statesave_module) | ||||
| 	{ | ||||
| 		g_free((*configuration)->statesave_module); | ||||
| 	} | ||||
|  | ||||
| 	if ((*configuration)->protocol_modules) | ||||
| 	{ | ||||
| 		g_strfreev((*configuration)->protocol_modules); | ||||
| 	} | ||||
|  | ||||
| 	g_free((*configuration)); | ||||
|  | ||||
| 	*configuration = NULL; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| wmud_configfile_read(gchar *filename, wMUDConfiguration **configuration, GError **error) | ||||
| { | ||||
| 	GKeyFile *configfile; | ||||
| 	GError *file_error = NULL; | ||||
| 	gchar **grouplist, | ||||
| 	      **group; | ||||
| 	wMUDConfiguration *conf; | ||||
|         | ||||
| 	*configuration = NULL; | ||||
|  | ||||
| 	Context; | ||||
|  | ||||
| 	if (filename == NULL) | ||||
| 	{ | ||||
| 		return FALSE; | ||||
| 	} | ||||
|  | ||||
| 	conf = g_new0(wMUDConfiguration, 1); | ||||
|  | ||||
| 	wmud_log_debug("Reading configuration file %s", filename); | ||||
|  | ||||
| 	configfile = g_key_file_new(); | ||||
|  | ||||
| 	if (!g_key_file_load_from_file(configfile, filename, G_KEY_FILE_NONE, &file_error)) | ||||
| 	{ | ||||
| 		if (file_error->domain == G_FILE_ERROR) | ||||
| 		{ | ||||
| 			wmud_log_error("Unable to open configuration file (%s): %s", filename, file_error->message); | ||||
| 		} | ||||
|  | ||||
| 		if (file_error->domain == G_KEY_FILE_ERROR) | ||||
| 		{ | ||||
| 			wmud_log_error("Unable to parse configuration file (%s): %s", filename, file_error->message); | ||||
| 		} | ||||
|  | ||||
| 		g_key_file_free(configfile); | ||||
|  | ||||
| 		return FALSE; | ||||
| 	} | ||||
|  | ||||
| 	grouplist = g_key_file_get_groups(configfile, NULL); | ||||
|  | ||||
| 	for (group = grouplist; *group; group++) | ||||
| 	{ | ||||
| 		gchar **keylist, | ||||
| 		      **key; | ||||
| 		wmud_log_debug("Processing group: [%s]", *group); | ||||
|  | ||||
| 		keylist = g_key_file_get_keys(configfile, *group, NULL, NULL); | ||||
|  | ||||
| 		for (key = keylist; *key; key++) | ||||
| 		{ | ||||
| 			gchar *value; | ||||
| 			gboolean line_processed; | ||||
|  | ||||
| 			value = g_key_file_get_value(configfile, *group, *key, NULL); | ||||
|  | ||||
| 			line_processed = _wmud_config_process_value(conf, *group, *key, value); | ||||
|  | ||||
| 			g_free(value); | ||||
|  | ||||
| 			if (!line_processed) | ||||
| 			{ | ||||
| 				g_strfreev(keylist); | ||||
| 				g_strfreev(grouplist); | ||||
| 				g_key_file_free(configfile); | ||||
|  | ||||
| 				return FALSE; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		g_strfreev(keylist); | ||||
| 	} | ||||
|  | ||||
| 	g_strfreev(grouplist); | ||||
|  | ||||
| 	g_key_file_free(configfile); | ||||
|  | ||||
| 	/* If one of the logging options not found, fall back to the "log" | ||||
| 	 * option. If neither log can be found, configuration is invalid | ||||
| 	 */ | ||||
| #ifdef DEBUG | ||||
| 	if (!conf->debug_log_found) | ||||
| 	{ | ||||
| 		if (!conf->log_found) | ||||
| 		{ | ||||
| 			wmud_log_error("Debug log not found in configuration file"); | ||||
| 			wmud_configuration_free(&conf); | ||||
| 			return FALSE; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			conf->debug_log_found = TRUE; | ||||
| 			conf->debug_log_dest = conf->log_dest; | ||||
| 			conf->debug_logfile = (conf->logfile == NULL) ? NULL : g_strdup(conf->logfile); | ||||
| 		} | ||||
| 	} | ||||
| #endif | ||||
| 	if (!conf->info_log_found) | ||||
| 	{ | ||||
| 		if (!conf->log_found) | ||||
| 		{ | ||||
| 			wmud_log_error("Info log not found in configuration file"); | ||||
| 			wmud_configuration_free(&conf); | ||||
| 			return FALSE; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			conf->info_log_found = TRUE; | ||||
| 			conf->info_log_dest = conf->log_dest; | ||||
| 			conf->info_logfile = (conf->logfile == NULL) ? NULL : g_strdup(conf->logfile); | ||||
| 		} | ||||
| 	} | ||||
| 	if (!conf->warning_log_found) | ||||
| 	{ | ||||
| 		if (!conf->log_found) | ||||
| 		{ | ||||
| 			wmud_log_error("Warning log not found in configuration file"); | ||||
| 			wmud_configuration_free(&conf); | ||||
| 			return FALSE; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			conf->warning_log_found = TRUE; | ||||
| 			conf->warning_log_dest = conf->log_dest; | ||||
| 			conf->warning_logfile = (conf->logfile == NULL) ? NULL : g_strdup(conf->logfile); | ||||
| 		} | ||||
| 	} | ||||
| 	if (!conf->error_log_found) | ||||
| 	{ | ||||
| 		if (!conf->log_found) | ||||
| 		{ | ||||
| 			wmud_log_error("Error log not found in configuration file"); | ||||
| 			wmud_configuration_free(&conf); | ||||
| 			return FALSE; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			conf->error_log_found = TRUE; | ||||
| 			conf->error_log_dest = conf->log_dest; | ||||
| 			conf->error_logfile = (conf->logfile == NULL) ? NULL : g_strdup(conf->logfile); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* If daemonizing is forced, we cannot log to the console. However, | ||||
| 	 * daemonizing is not supported if DEBUG is turned on | ||||
| 	 */ | ||||
| #ifdef DEBUG | ||||
| 	if ((conf->daemonize == WMUD_CONF_DAEMONIZE_FORCE) || (conf->daemonize == WMUD_CONF_DAEMONIZE_YES)) | ||||
| 	{ | ||||
| 		wmud_log_warning("Cannot daemonize in DEBUG mode"); | ||||
| 		conf->daemonize = WMUD_CONF_DAEMONIZE_NO; | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	if (conf->daemonize == WMUD_CONF_DAEMONIZE_FORCE) | ||||
| 	{ | ||||
| #ifdef DEBUG | ||||
| 		if (conf->debug_log_dest == WMUD_CONF_LOG_CONSOLE) | ||||
| 		{ | ||||
| 			wmud_log_warning("Cannot log to console when daemonized. Debug log is falling back to syslog"); | ||||
| 			conf->debug_log_dest = WMUD_CONF_LOG_SYSLOG; | ||||
| 		} | ||||
| #endif | ||||
| 		if (conf->info_log_dest == WMUD_CONF_LOG_CONSOLE) | ||||
| 		{ | ||||
| 			wmud_log_warning("Cannot log to console when daemonized. Info log is falling back to syslog"); | ||||
| 			conf->info_log_dest = WMUD_CONF_LOG_SYSLOG; | ||||
| 		} | ||||
| 		if (conf->warning_log_dest == WMUD_CONF_LOG_CONSOLE) | ||||
| 		{ | ||||
| 			wmud_log_warning("Cannot log to console when daemonized. Warning log is falling back to syslog"); | ||||
| 			conf->warning_log_dest = WMUD_CONF_LOG_SYSLOG; | ||||
| 		} | ||||
| 		if (conf->error_log_dest == WMUD_CONF_LOG_CONSOLE) | ||||
| 		{ | ||||
| 			wmud_log_warning("Cannot log to console when daemonized. Error log is falling back to syslog"); | ||||
| 			conf->error_log_dest = WMUD_CONF_LOG_SYSLOG; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| #ifdef DEBUG | ||||
| 	wmud_log_warning("Logging must be sent to the console in debug mode!"); | ||||
| 	if (conf->debug_log_dest != WMUD_CONF_LOG_CONSOLE) | ||||
| 	{ | ||||
| 		if (conf->debug_logfile) | ||||
| 		{ | ||||
| 			g_free(conf->debug_logfile); | ||||
| 			conf->debug_logfile = NULL; | ||||
| 		} | ||||
| 		conf->debug_log_dest = WMUD_CONF_LOG_CONSOLE; | ||||
| 	} | ||||
| 	if (conf->info_log_dest != WMUD_CONF_LOG_CONSOLE) | ||||
| 	{ | ||||
| 		if (conf->info_logfile) | ||||
| 		{ | ||||
| 			g_free(conf->info_logfile); | ||||
| 			conf->info_logfile = NULL; | ||||
| 		} | ||||
| 		conf->info_log_dest = WMUD_CONF_LOG_CONSOLE; | ||||
| 	} | ||||
| 	if (conf->warning_log_dest != WMUD_CONF_LOG_CONSOLE) | ||||
| 	{ | ||||
| 		if (conf->warning_logfile) | ||||
| 		{ | ||||
| 			g_free(conf->warning_logfile); | ||||
| 			conf->warning_logfile = NULL; | ||||
| 		} | ||||
| 		conf->warning_log_dest = WMUD_CONF_LOG_CONSOLE; | ||||
| 	} | ||||
| 	if (conf->error_log_dest != WMUD_CONF_LOG_CONSOLE) | ||||
| 	{ | ||||
| 		if (conf->error_logfile) | ||||
| 		{ | ||||
| 			g_free(conf->error_logfile); | ||||
| 			conf->error_logfile = NULL; | ||||
| 		} | ||||
| 		conf->error_log_dest = WMUD_CONF_LOG_CONSOLE; | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	*configuration = conf; | ||||
| 	return TRUE; | ||||
| } | ||||
|  | ||||
							
								
								
									
										16
									
								
								src/configfile.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/configfile.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| #ifndef __WMUD_CORE_CONFIGFILE_H__ | ||||
| #define __WMUD_CORE_CONFIGFILE_H__ | ||||
|  | ||||
| #include <glib.h> | ||||
|  | ||||
| #include "wmud-session.h" | ||||
|  | ||||
| #include "configfile-module.h" | ||||
|  | ||||
| extern wMUDConfiguration *wmud_configuration; | ||||
|  | ||||
| gboolean wmud_configfile_read(gchar *filename, wMUDConfiguration **configuration, GError **error); | ||||
| void wmud_configuration_free(wMUDConfiguration **configuration); | ||||
|  | ||||
| #endif /* __WMUD_CORE_CONFIGFILE_H__ */ | ||||
|  | ||||
							
								
								
									
										107
									
								
								src/irc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								src/irc.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,107 @@ | ||||
| #include <string.h> | ||||
| #include <glib.h> | ||||
| #include <gnet.h> | ||||
|  | ||||
| #include "wmud.h" | ||||
| #include "logger.h" | ||||
|  | ||||
| #define COMMAND_DELIMITERS " \t\n\r" | ||||
|  | ||||
| struct _wMUDSplitHelper | ||||
| { | ||||
| 	gchar **list; | ||||
| 	gint position; | ||||
| }; | ||||
|  | ||||
| static void | ||||
| _add_words(gpointer data, gpointer user_data) | ||||
| { | ||||
| 	struct _wMUDSplitHelper *split_data = (struct _wMUDSplitHelper *)user_data; | ||||
| 	gchar *word = (gchar *)data; | ||||
|  | ||||
| 	split_data->list[split_data->position] = word; | ||||
| 	split_data->position++; | ||||
| } | ||||
|  | ||||
| static gint | ||||
| _wmud_split_irc_line(gchar *command, gchar ***list) | ||||
| { | ||||
| 	gchar *a; | ||||
| 	gint word_started_at = 0; | ||||
| 	gboolean was_in_word = FALSE; | ||||
| 	gboolean in_string = TRUE; | ||||
| 	guint colon_at = -1; | ||||
| 	GSList *word_list = NULL; | ||||
| 	gchar **ret; | ||||
| 	 | ||||
| 	struct _wMUDSplitHelper split_data; | ||||
| 	gint word_count; | ||||
|  | ||||
| 	Context; | ||||
|  | ||||
| 	for (a = command; in_string; a++) | ||||
| 	{ | ||||
| 		if (*a == 0) | ||||
| 		{ | ||||
| 			in_string = FALSE; | ||||
| 		} | ||||
| 		if ( | ||||
| 				(*a == 0) | ||||
| 				|| ( | ||||
| 					(colon_at == -1) | ||||
| 					&& strchr(COMMAND_DELIMITERS, *a) | ||||
| 				) | ||||
| 				|| ( | ||||
| 					(colon_at == -1) | ||||
| 					&& (*a == ':') | ||||
| 				) | ||||
| 			) | ||||
| 		{ | ||||
| 			if (was_in_word) | ||||
| 			{ | ||||
| 				was_in_word = FALSE; | ||||
| 				word_list = g_slist_append(word_list, g_strndup((command + word_started_at), (a - command) - word_started_at)); | ||||
| 				word_started_at = (a - command); | ||||
| 			} | ||||
| 			if ((*a == ':') && (colon_at == -1)) | ||||
| 			{ | ||||
| 				colon_at = (a - command) - 1; | ||||
| 				if (colon_at == -1) | ||||
| 				{ | ||||
| 					colon_at = 0; | ||||
| 				} | ||||
| 			} | ||||
| 			word_started_at++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		was_in_word = TRUE; | ||||
| 	} | ||||
| 	 | ||||
| 	word_count = g_slist_length(word_list); | ||||
| 	Context ret = g_new0(gchar *, word_count + 1); | ||||
|  | ||||
| 	split_data.list = ret; | ||||
| 	split_data.position = 0; | ||||
|  | ||||
| 	g_slist_foreach(word_list, _add_words, &split_data); | ||||
| 	g_slist_free(word_list); | ||||
|  | ||||
| 	if (list != NULL) | ||||
| 	{ | ||||
| 		Context *list = ret; | ||||
| 	} | ||||
|  | ||||
| 	return word_count; | ||||
| } | ||||
|  | ||||
| void | ||||
| wmud_process_irc_command(GConn *connection, gchar *command) | ||||
| { | ||||
| 	gchar **command_parts; | ||||
| 	gint word_count; | ||||
|  | ||||
| 	word_count = _wmud_split_irc_line(command, &command_parts); | ||||
|  | ||||
| 	wmud_log_debug("Got command '%s' with %d parts", command, word_count); | ||||
| } | ||||
|  | ||||
							
								
								
									
										10
									
								
								src/irc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/irc.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| #ifndef __WMUD_CORE_IRC_H__ | ||||
| #define __WMUD_CORE_IRC_H__ | ||||
|  | ||||
| #include <glib.h> | ||||
| #include <gnet.h> | ||||
|  | ||||
| void wmud_process_irc_command(GConn *connection, gchar *command); | ||||
|  | ||||
| #endif /* __WMUD_CORE_IRC_H__ */ | ||||
|  | ||||
							
								
								
									
										22
									
								
								src/logger-module.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/logger-module.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| #ifndef __WMUD_MODULE_LOGGER_H__ | ||||
| #define __WMUD_MODULE_LOGGER_H__ | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
| 	WMUD_LOG_DEBUG, | ||||
| 	WMUD_LOG_INFO, | ||||
| 	WMUD_LOG_WARN, | ||||
| 	WMUD_LOG_ERROR | ||||
| } wMUDLogLevelType; | ||||
|  | ||||
| #define wmud_log_info(x, ...)    wmud_log(WMUD_LOG_INFO,  __FILE__, __LINE__, x, ## __VA_ARGS__) | ||||
| #define wmud_log_warning(x, ...) wmud_log(WMUD_LOG_WARN,  __FILE__, __LINE__, x, ## __VA_ARGS__) | ||||
| #define wmud_log_error(x, ...)   wmud_log(WMUD_LOG_ERROR, __FILE__, __LINE__, x, ## __VA_ARGS__) | ||||
| #if DEBUG | ||||
| #define wmud_log_debug(x, ...)   wmud_log(WMUD_LOG_DEBUG, __FILE__, __LINE__, x, ## __VA_ARGS__) | ||||
| #else /* ! DEBUG */ | ||||
| #define wmud_log_debug(x, ...) | ||||
| #endif /* DEBUG */ | ||||
|  | ||||
| #endif /* __WMUD_MODULE_LOGGER_H__ */ | ||||
|  | ||||
							
								
								
									
										232
									
								
								src/logger.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										232
									
								
								src/logger.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,232 @@ | ||||
| #include <glib.h> | ||||
|  | ||||
| #include <stdarg.h> | ||||
| #include <string.h> | ||||
| #include <syslog.h> | ||||
| #include <stdio.h> | ||||
| #include <libgnomevfs/gnome-vfs.h> | ||||
|  | ||||
| #include "wmud.h" | ||||
| #include "configfile.h" | ||||
| #include "logger.h" | ||||
|  | ||||
| enum { | ||||
| 	_LOG_DEST_STDOUT, | ||||
| 	_LOG_DEST_STDERR | ||||
| }; | ||||
|  | ||||
| typedef struct _wmud_message_level { | ||||
| 	int colorcode; | ||||
| 	const char *prefix; | ||||
| 	int debug_dest; | ||||
| 	wMUDConfigurationLogging dest; | ||||
| 	GnomeVFSHandle *logfile; | ||||
| } wMUDMessageLevelType; | ||||
|  | ||||
| wMUDMessageLevelType wMUDMessageLevels[] = { | ||||
| 	{ 35, "debug", _LOG_DEST_STDERR, WMUD_CONF_LOG_CONSOLE, NULL },  /* LOG_DEBUG */ | ||||
| 	{ 32, "info",  _LOG_DEST_STDOUT, WMUD_CONF_LOG_CONSOLE, NULL },  /* LOG_INFO  */ | ||||
| 	{ 33, "warn",  _LOG_DEST_STDOUT, WMUD_CONF_LOG_CONSOLE, NULL },  /* LOG_WARN  */ | ||||
| 	{ 31, "error", _LOG_DEST_STDERR, WMUD_CONF_LOG_CONSOLE, NULL }   /* LOG_ERROR */ | ||||
| }; | ||||
| #define wmud_message_level_count (sizeof(wmud_message_levels) / sizeof(wmud_message_level)) | ||||
|  | ||||
| static void | ||||
| _wmud_log_message(wMUDLogLevelType level, const char *filename, const int linenum, const char *fmt, va_list args) | ||||
| { | ||||
| 	char *format, | ||||
| 		 *final_string; | ||||
| 	wMUDMessageLevelType level_info = wMUDMessageLevels[level]; | ||||
| 	int syslog_level; | ||||
| 	static char *timestamp = NULL; | ||||
| 	time_t now; | ||||
|  | ||||
| 	if (timestamp == NULL) | ||||
| 	{ | ||||
| 		timestamp = g_malloc0(17 * sizeof(char)); | ||||
| 	} | ||||
|  | ||||
| 	switch (level_info.dest) | ||||
| 	{ | ||||
| 		case WMUD_CONF_LOG_NONE: | ||||
| 			return; | ||||
| 		case WMUD_CONF_LOG_FILE: | ||||
| 			now = time(NULL); | ||||
| 			Context strftime(timestamp, 16, "%b %e %H:%M:%S", localtime(&now)); | ||||
| 			Context gnome_vfs_seek(level_info.logfile, GNOME_VFS_SEEK_END, 0); | ||||
| 			format = g_strdup_printf("%s wMUD[%d]: [%s] %s:%d: %s\n", timestamp, wmud_pid, level_info.prefix, filename, linenum, fmt); | ||||
| 			final_string = g_strdup_vprintf(format, args); | ||||
| 			g_free(format); | ||||
| 			gnome_vfs_write(level_info.logfile, final_string, strlen(final_string), NULL); | ||||
| 			g_free(final_string); | ||||
| 			break; | ||||
| 		case WMUD_CONF_LOG_SYSLOG: | ||||
| 			switch (level) | ||||
| 			{ | ||||
| 				case WMUD_LOG_DEBUG: | ||||
| 					syslog_level = LOG_DEBUG; | ||||
| 					break; | ||||
| 				case WMUD_LOG_INFO: | ||||
| 					syslog_level = LOG_INFO; | ||||
| 					break; | ||||
| 				case WMUD_LOG_WARN: | ||||
| 					syslog_level = LOG_WARNING; | ||||
| 					break; | ||||
| 				case WMUD_LOG_ERROR: | ||||
| 					syslog_level = LOG_ERR; | ||||
| 					break; | ||||
| 				default: | ||||
| 					syslog_level = LOG_CRIT; | ||||
| 					break; | ||||
| 			} | ||||
| 			format = g_strdup_printf("[%s] %s:%d: %s\n", level_info.prefix, filename, linenum, fmt); | ||||
| 			vsyslog(LOG_USER | syslog_level, format, args); | ||||
| 			g_free(format); | ||||
| 			break; | ||||
| 		case WMUD_CONF_LOG_CONSOLE: | ||||
| 			format = g_strdup_printf("\x1b[%dm\x1b[1m[%s] %s:%d: %s\x1b[0m\n", level_info.colorcode, level_info.prefix, filename, linenum, fmt); | ||||
| 			vfprintf((level_info.debug_dest == _LOG_DEST_STDERR) ? stderr : stdout, format, args); | ||||
| 			g_free(format); | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void | ||||
| wmud_log(wMUDLogLevelType level, const char *filename, const int linenum, const char *fmt, ...) | ||||
| { | ||||
| 	va_list args; | ||||
|  | ||||
| 	va_start(args, fmt); | ||||
| 	_wmud_log_message(level, filename, linenum, fmt, args); | ||||
| 	va_end(args); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| wmud_logger_init(wMUDConfiguration *config) | ||||
| { | ||||
| 	gchar *full_logfile_uri; | ||||
| 	GnomeVFSURI *log_uri; | ||||
|  | ||||
| 	g_assert(config != NULL); | ||||
|  | ||||
| 	if (config->debug_log_dest == WMUD_CONF_LOG_FILE) | ||||
| 	{ | ||||
| 		GnomeVFSResult state; | ||||
| 		full_logfile_uri = gnome_vfs_get_uri_from_local_path(config->debug_logfile); | ||||
| 		log_uri = gnome_vfs_uri_new(full_logfile_uri); | ||||
| 		g_free(full_logfile_uri); | ||||
|  | ||||
| 		switch (gnome_vfs_open_uri(&(wMUDMessageLevels[WMUD_LOG_DEBUG].logfile), log_uri, GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_WRITE | GNOME_VFS_OPEN_RANDOM)) | ||||
| 		{ | ||||
| 			case GNOME_VFS_ERROR_NOT_FOUND: | ||||
| 				if ((state = gnome_vfs_create_uri(&(wMUDMessageLevels[WMUD_LOG_DEBUG].logfile), log_uri, GNOME_VFS_OPEN_WRITE, FALSE, 0640)) != GNOME_VFS_OK) | ||||
| 				{ | ||||
| 					wmud_log_error("Unable to open debug logfile (%s)", config->debug_logfile); | ||||
| 					wmud_shutdown(); | ||||
| 					return FALSE; | ||||
| 				} | ||||
| 				break; | ||||
| 			case GNOME_VFS_OK: | ||||
| 				break; | ||||
| 			default: | ||||
| 				wmud_log_error("Unprocessed return state from gnome_vfs_open_uri()"); | ||||
| 				break; | ||||
| 		} | ||||
| 		gnome_vfs_uri_unref(log_uri); | ||||
| 	} | ||||
| 	wMUDMessageLevels[WMUD_LOG_DEBUG].dest = config->debug_log_dest; | ||||
|  | ||||
| 	if (config->info_log_dest == WMUD_CONF_LOG_FILE) | ||||
| 	{ | ||||
| 		GnomeVFSResult state; | ||||
| 		full_logfile_uri = gnome_vfs_get_uri_from_local_path(config->info_logfile); | ||||
| 		log_uri = gnome_vfs_uri_new(full_logfile_uri); | ||||
| 		g_free(full_logfile_uri); | ||||
|  | ||||
| 		switch (gnome_vfs_open_uri(&(wMUDMessageLevels[WMUD_LOG_INFO].logfile), log_uri, GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_WRITE | GNOME_VFS_OPEN_RANDOM)) | ||||
| 		{ | ||||
| 			case GNOME_VFS_ERROR_NOT_FOUND: | ||||
| 				if ((state = gnome_vfs_create_uri(&(wMUDMessageLevels[WMUD_LOG_INFO].logfile), log_uri, GNOME_VFS_OPEN_WRITE, FALSE, 0640)) != GNOME_VFS_OK) | ||||
| 				{ | ||||
| 					wmud_log_error("Unable to open info logfile (%s)", config->info_logfile); | ||||
| 					wmud_shutdown(); | ||||
| 					return FALSE; | ||||
| 				} | ||||
| 				break; | ||||
| 			case GNOME_VFS_OK: | ||||
| 				break; | ||||
| 			default: | ||||
| 				wmud_log_error("Unprocessed return state from gnome_vfs_open_uri()"); | ||||
| 				break; | ||||
| 		} | ||||
| 		gnome_vfs_uri_unref(log_uri); | ||||
| 	} | ||||
| 	wMUDMessageLevels[WMUD_LOG_INFO].dest = config->info_log_dest; | ||||
|  | ||||
| 	if (config->warning_log_dest == WMUD_CONF_LOG_FILE) | ||||
| 	{ | ||||
| 		GnomeVFSResult state; | ||||
| 		full_logfile_uri = gnome_vfs_get_uri_from_local_path(config->warning_logfile); | ||||
| 		log_uri = gnome_vfs_uri_new(full_logfile_uri); | ||||
| 		g_free(full_logfile_uri); | ||||
|  | ||||
| 		switch (gnome_vfs_open_uri(&(wMUDMessageLevels[WMUD_LOG_WARN].logfile), log_uri, GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_WRITE | GNOME_VFS_OPEN_RANDOM)) | ||||
| 		{ | ||||
| 			case GNOME_VFS_ERROR_NOT_FOUND: | ||||
| 				if ((state = gnome_vfs_create_uri(&(wMUDMessageLevels[WMUD_LOG_WARN].logfile), log_uri, GNOME_VFS_OPEN_WRITE, FALSE, 0640)) != GNOME_VFS_OK) | ||||
| 				{ | ||||
| 					wmud_log_error("Unable to open warning logfile (%s)", config->warning_logfile); | ||||
| 					wmud_shutdown(); | ||||
| 					return FALSE; | ||||
| 				} | ||||
| 				break; | ||||
| 			case GNOME_VFS_OK: | ||||
| 				break; | ||||
| 			default: | ||||
| 				wmud_log_error("Unprocessed return state from gnome_vfs_open_uri()"); | ||||
| 				break; | ||||
| 		} | ||||
| 		gnome_vfs_uri_unref(log_uri); | ||||
| 	} | ||||
| 	wMUDMessageLevels[WMUD_LOG_WARN].dest = config->warning_log_dest; | ||||
|  | ||||
| 	if (config->error_log_dest == WMUD_CONF_LOG_FILE) | ||||
| 	{ | ||||
| 		GnomeVFSResult state; | ||||
| 		full_logfile_uri = gnome_vfs_get_uri_from_local_path(config->error_logfile); | ||||
| 		log_uri = gnome_vfs_uri_new(full_logfile_uri); | ||||
| 		g_free(full_logfile_uri); | ||||
|  | ||||
| 		switch (gnome_vfs_open_uri(&(wMUDMessageLevels[WMUD_LOG_ERROR].logfile), log_uri, GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_WRITE | GNOME_VFS_OPEN_RANDOM)) | ||||
| 		{ | ||||
| 			case GNOME_VFS_ERROR_NOT_FOUND: | ||||
| 				if ((state = gnome_vfs_create_uri(&(wMUDMessageLevels[WMUD_LOG_ERROR].logfile), log_uri, GNOME_VFS_OPEN_WRITE, FALSE, 0640)) != GNOME_VFS_OK) | ||||
| 				{ | ||||
| 					wmud_log_error("Unable to open error logfile (%s)", config->error_logfile); | ||||
| 					wmud_shutdown(); | ||||
| 					return FALSE; | ||||
| 				} | ||||
| 				break; | ||||
| 			case GNOME_VFS_OK: | ||||
| 				break; | ||||
| 			default: | ||||
| 				wmud_log_error("Unprocessed return state from gnome_vfs_open_uri()"); | ||||
| 				break; | ||||
| 		} | ||||
| 		gnome_vfs_uri_unref(log_uri); | ||||
| 	} | ||||
| 	wMUDMessageLevels[WMUD_LOG_ERROR].dest = config->error_log_dest; | ||||
|  | ||||
| 	if ( | ||||
| 			(config->debug_log_dest == WMUD_CONF_LOG_SYSLOG) | ||||
| 			|| (config->info_log_dest == WMUD_CONF_LOG_SYSLOG) | ||||
| 			|| (config->warning_log_dest == WMUD_CONF_LOG_SYSLOG) | ||||
| 			|| (config->error_log_dest == WMUD_CONF_LOG_SYSLOG) | ||||
| 	) | ||||
| 	{ | ||||
| 		openlog("wMUD", LOG_PID, LOG_USER); | ||||
| 	} | ||||
|  | ||||
| 	return TRUE; | ||||
| } | ||||
|  | ||||
							
								
								
									
										16
									
								
								src/logger.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/logger.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| #ifndef __WMUD_CORE_LOGGER_H__ | ||||
| #define __WMUD_CORE_LOGGER_H__ | ||||
|  | ||||
| #include <stdarg.h> | ||||
| #include <glib.h> | ||||
|  | ||||
| #include "configfile.h" | ||||
|  | ||||
| #include "logger-module.h" | ||||
| #include "wmud-module.h" | ||||
|  | ||||
| void wmud_log(wMUDLogLevelType level, const char *filename, const int linenum, const char *fmt, ...); | ||||
| gboolean wmud_logger_init(wMUDConfiguration *config); | ||||
|  | ||||
| #endif /* __WMUD_CORE_LOGGER_H__ */ | ||||
|  | ||||
							
								
								
									
										10
									
								
								src/module.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/module.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| #ifndef __WMUD_MODULE_H__  | ||||
| #define __WMUD_MODULE_H__ | ||||
|  | ||||
| #include "wmud-module.h" | ||||
|  | ||||
| #define wmud_log(level, filename, linenum, fmt, ...) ((void (*)(wMUDLogLevelType, const char *, const int, const char *, ...))(wMUDCallables[WMUD_CALLABLE_WMUD_LOG]))(level, filename, linenum, fmt, ## __VA_ARGS__) | ||||
| #define wmud_print_context(filename, linenum) ((void (*)(char *, int))(wMUDCallables[WMUD_CALLABLE_WMUD_PRINT_CONTEXT]))(filename, linenum) | ||||
|  | ||||
| #endif /* __WMUD_MODULE_H__ */ | ||||
|  | ||||
							
								
								
									
										112
									
								
								src/modules.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								src/modules.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | ||||
| #include <glib.h> | ||||
| #include <gmodule.h> | ||||
|  | ||||
| #if HAVE_CONFIG_H | ||||
| #include "config.h" | ||||
| #endif /* HAVE_CONFIG_H */ | ||||
|  | ||||
| #include "modules.h" | ||||
| #include "configfile.h" | ||||
| #include "logger.h" | ||||
| #include "wmud.h" | ||||
|  | ||||
| #include "wmud-module.h" | ||||
|  | ||||
| static GModule *statesave_module = NULL; | ||||
|  | ||||
| gboolean (*wmud_save_state)(GError **error) = NULL; | ||||
| gpointer wMUDCallables[WMUD_CALLABLE_LAST]; | ||||
|  | ||||
| void | ||||
| wmud_fill_callable_table(void) | ||||
| { | ||||
| 	wMUDCallables[WMUD_CALLABLE_WMUD_LOG] = wmud_log; | ||||
| #ifdef DEBUG | ||||
| 	wMUDCallables[WMUD_CALLABLE_WMUD_PRINT_CONTEXT] = wmud_print_context; | ||||
| #endif /* DEBUG */ | ||||
| 	wMUDCallables[WMUD_CALLABLE_LAST] = NULL; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| wmud_load_config_modules(wMUDConfiguration *config) | ||||
| { | ||||
| 	gchar *statesave_module_short_name, | ||||
| 		  *statesave_module_file, | ||||
| 		  *func_name; | ||||
| 	gboolean (*module_is_statesaving)(void); | ||||
| 	gboolean (*module_load)(wMUDConfiguration *config); | ||||
|  | ||||
| 	if (!g_module_supported()) | ||||
| 	{ | ||||
| 		wmud_log_error("Module loading is not supported!"); | ||||
| 		return FALSE; | ||||
| 	} | ||||
| 	Context; | ||||
|  | ||||
| 	if (config->modules_dir == NULL) | ||||
| 	{ | ||||
| 		wmud_log_error("Module directory must be set in the configfile!"); | ||||
| 		return FALSE; | ||||
| 	} | ||||
|  | ||||
| 	if (config->statesave_module == NULL) | ||||
| 	{ | ||||
| 		wmud_log_error("State saving module must be set in the configfile!"); | ||||
| 		return FALSE; | ||||
| 	} | ||||
|  | ||||
| 	statesave_module_short_name = g_strdup_printf("state-%s", config->statesave_module); | ||||
| 	statesave_module_file = g_module_build_path(config->modules_dir, statesave_module_short_name); | ||||
| 	g_free(statesave_module_short_name); | ||||
|  | ||||
| 	wmud_log_debug("Trying to load \"%s\" as state-saving module", statesave_module_file); | ||||
|  | ||||
| 	if ((statesave_module = g_module_open(statesave_module_file, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL)) == NULL) | ||||
| 	{ | ||||
| 		wmud_log_error("Unable to load state saving module %s", statesave_module_file); | ||||
| 		return FALSE; | ||||
| 	} | ||||
|  | ||||
| 	func_name = g_strdup_printf("wmud_statesave_%s_is_statesave", config->statesave_module); | ||||
| 	if (g_module_symbol(statesave_module, func_name, (gpointer *)&module_is_statesaving)) | ||||
| 	{ | ||||
| 		if (!module_is_statesaving()) | ||||
| 		{ | ||||
| 			wmud_log_error("Module %s is not marked as statesaving!", statesave_module_file); | ||||
| 			g_module_close(statesave_module); | ||||
| 			g_free(func_name); | ||||
| 			return FALSE; | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		wmud_log_error("Undefined symbol \"%s\" in statesave module %s", func_name, statesave_module_file); | ||||
| 		g_module_close(statesave_module); | ||||
| 		g_free(func_name); | ||||
| 		return FALSE; | ||||
| 	} | ||||
| 	g_free(func_name); | ||||
|  | ||||
| 	func_name = g_strdup_printf("wmud_statesave_%s_load", config->statesave_module); | ||||
| 	if (g_module_symbol(statesave_module, func_name, (gpointer *)&module_load)) | ||||
| 	{ | ||||
| 		if (!module_load(config)) | ||||
| 		{ | ||||
| 			wmud_log_error("Module initialization failed for %s", statesave_module_file); | ||||
| 			g_module_close(statesave_module); | ||||
| 			g_free(func_name); | ||||
| 			return FALSE; | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		wmud_log_error("Undefined symbol \"%s\" in statesave module %s", func_name, statesave_module_file); | ||||
| 		g_module_close(statesave_module); | ||||
| 		g_free(func_name); | ||||
| 		return FALSE; | ||||
| 	} | ||||
|  | ||||
| 	g_free(statesave_module_file); | ||||
| 	return TRUE; | ||||
| } | ||||
|  | ||||
							
								
								
									
										12
									
								
								src/modules.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/modules.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| #ifndef __WMUD_CORE_MODULES_H__ | ||||
| #define __WMUD_CORE_MODULES_H__ | ||||
|  | ||||
| #include <glib.h> | ||||
|  | ||||
| #include "configfile.h" | ||||
|  | ||||
| void wmud_fill_callable_table(void); | ||||
| gboolean wmud_load_config_modules(wMUDConfiguration *config); | ||||
|  | ||||
| #endif /* __WMUD_CORE_MODULES_H__ */ | ||||
|  | ||||
							
								
								
									
										427
									
								
								src/networking.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										427
									
								
								src/networking.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,427 @@ | ||||
| #include <glib.h> | ||||
| #include <gnet.h> | ||||
|  | ||||
| #include <string.h> | ||||
|  | ||||
| #ifdef HAVE_CONFIG_H | ||||
| #include "config.h" | ||||
| #endif /* HAVE_CONFIG_H */ | ||||
|  | ||||
| #include "wmud.h" | ||||
| #include "logger.h" | ||||
| #include "sessions.h" | ||||
| #include "networking.h" | ||||
| #include "configfile.h" | ||||
| #include "commands.h" | ||||
| #include "irc.h" | ||||
|  | ||||
| #define LISTEN_PORT 4000 | ||||
|  | ||||
| GSList *_wmud_active_interfaces = NULL; | ||||
|  | ||||
| /** | ||||
|  * _wmud_telnet_event: | ||||
|  * @connection: the #GConn on which this event occured | ||||
|  * @event: type of event | ||||
|  * @user_data: user data arrived with this function call. Currently it is not used | ||||
|  * | ||||
|  * Callback function which gets called whenever a new event occurs on a telnet-type socket | ||||
|  */ | ||||
| static void | ||||
| _wmud_telnet_event(GConn *connection, GConnEvent *event, gpointer user_data) | ||||
| { | ||||
| 	gchar *command; | ||||
| 	GError *error = NULL; | ||||
|  | ||||
| 	//Context; | ||||
|  | ||||
| 	switch (event->type) | ||||
| 	{ | ||||
| 		case GNET_CONN_READABLE: | ||||
| 			command = NULL; | ||||
| 			gsize term_pos; | ||||
| 			gsize length; | ||||
|  | ||||
| 			switch (g_io_channel_read_line(connection->iochannel, &command, &length, &term_pos, &error)) | ||||
| 			{ | ||||
| 				case G_IO_STATUS_ERROR: | ||||
| 					wmud_log_error("Telnet read error: %s", error->message); | ||||
| 					break; | ||||
| 				case G_IO_STATUS_NORMAL: | ||||
| 					wmud_log_debug("Accepted data"); | ||||
| 					break; | ||||
| 				case G_IO_STATUS_EOF: | ||||
| 					wmud_log_info("Client disconnected"); | ||||
| 					wmud_connection_disconnect(connection); | ||||
| 					break; | ||||
| 				case G_IO_STATUS_AGAIN: | ||||
| 					wmud_log_debug("Telnet read terminated, trying again"); | ||||
| 					break; | ||||
| 				default: | ||||
| 					break; | ||||
| 			} | ||||
| 			if (command) | ||||
| 			{ | ||||
| 				*(command + term_pos) = 0; | ||||
| 				wmud_log_debug("Got command: %s", command); | ||||
| 				wmud_process_command(connection, command); | ||||
| 				*(command + term_pos) = '\n'; | ||||
| 				g_free(command); | ||||
| 			} | ||||
| 			break; | ||||
| 		case GNET_CONN_TIMEOUT: | ||||
| 			wmud_log_info("Telnet connection timeout"); | ||||
| 			wmud_connection_disconnect(connection); | ||||
| 			break; | ||||
| 		case GNET_CONN_ERROR: | ||||
| 			wmud_log_error("Unprocessed connection event CONN_ERROR"); | ||||
| 			break; | ||||
| 		case GNET_CONN_CONNECT: | ||||
| 			wmud_log_error("Unprocessed connection event CONN_CONNECT"); | ||||
| 			break; | ||||
| 		case GNET_CONN_CLOSE: | ||||
| 			wmud_log_error("Unprocessed connection event CONN_CLOSE"); | ||||
| 			break; | ||||
| 		case GNET_CONN_READ: | ||||
| 			wmud_log_error("Unprocessed connection event CONN_READ"); | ||||
| 			break; | ||||
| 		case GNET_CONN_WRITE: | ||||
| 			wmud_log_error("Unprocessed connection event CONN_WRITE"); | ||||
| 			break; | ||||
| 		case GNET_CONN_WRITABLE: | ||||
| 			wmud_log_error("Unprocessed connection event CONN_WRITABLE"); | ||||
| 			break; | ||||
| 		default: | ||||
| 			wmud_log_error("Got an unknown connction event from GNet!"); | ||||
| 			break; | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| static void | ||||
| _wmud_irc_event(GConn *connection, GConnEvent *event, gpointer user_data) | ||||
| { | ||||
| 	gchar *command; | ||||
| 	GError *error = NULL; | ||||
|  | ||||
| 	switch (event->type) | ||||
| 	{ | ||||
| 		case GNET_CONN_READABLE: | ||||
| 			command = NULL; | ||||
| 			gsize term_pos; | ||||
| 			gsize length; | ||||
|  | ||||
| 			switch (g_io_channel_read_line(connection->iochannel, &command, &length, &term_pos, &error)) | ||||
| 			{ | ||||
| 				case G_IO_STATUS_ERROR: | ||||
| 					wmud_log_error("IRC read error: %s", error->message); | ||||
| 					break; | ||||
| 				case G_IO_STATUS_NORMAL: | ||||
| 					wmud_log_debug("Accepted data"); | ||||
| 					break; | ||||
| 				case G_IO_STATUS_EOF: | ||||
| 					wmud_log_info("Client disconnected"); | ||||
| 					wmud_connection_disconnect(connection); | ||||
| 					break; | ||||
| 				case G_IO_STATUS_AGAIN: | ||||
| 					wmud_log_debug("IRC read terminated, trying again"); | ||||
| 					break; | ||||
| 				default: | ||||
| 					break; | ||||
| 			} | ||||
| 			if (command) | ||||
| 			{ | ||||
| 				*(command + term_pos) = 0; | ||||
| 				wmud_log_debug("Got command: %s", command); | ||||
| 				wmud_process_irc_command(connection, command); | ||||
| 				*(command + term_pos) = '\n'; | ||||
| 				g_free(command); | ||||
| 			} | ||||
| 			break; | ||||
| 		case GNET_CONN_TIMEOUT: | ||||
| 			wmud_log_info("IRC connection timeout"); | ||||
| 			wmud_connection_disconnect(connection); | ||||
| 			break; | ||||
| 		case GNET_CONN_ERROR: | ||||
| 			wmud_log_error("Unprocessed connection event CONN_ERROR"); | ||||
| 			break; | ||||
| 		case GNET_CONN_CONNECT: | ||||
| 			wmud_log_error("Unprocessed connection event CONN_CONNECT"); | ||||
| 			break; | ||||
| 		case GNET_CONN_CLOSE: | ||||
| 			wmud_log_error("Unprocessed connection event CONN_CLOSE"); | ||||
| 			break; | ||||
| 		case GNET_CONN_READ: | ||||
| 			wmud_log_error("Unprocessed connection event CONN_READ"); | ||||
| 			break; | ||||
| 		case GNET_CONN_WRITE: | ||||
| 			wmud_log_error("Unprocessed connection event CONN_WRITE"); | ||||
| 			break; | ||||
| 		case GNET_CONN_WRITABLE: | ||||
| 			wmud_log_error("Unprocessed connection event CONN_WRITABLE"); | ||||
| 			break; | ||||
| 		default: | ||||
| 			wmud_log_error("Got an unknown connction event from GNet!"); | ||||
| 			break; | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| void | ||||
| wmud_connection_send(GConn *connection, gchar *fmt, ...) | ||||
| { | ||||
| 	va_list args; | ||||
| 	gchar *buffer, | ||||
| 	      *send_buffer; | ||||
| 	gsize len; | ||||
| 	GError *error = NULL; | ||||
| 	GIOStatus status; | ||||
|  | ||||
| 	va_start(args, fmt); | ||||
| 	Context buffer = g_strdup_vprintf(fmt, args); | ||||
| 	va_end(args); | ||||
|  | ||||
| 	Context send_buffer = g_strdup_printf("%s%s", buffer, wmud_connection_get_linebreak(connection)); | ||||
| 	Context g_free(buffer); | ||||
|  | ||||
| 	/* TODO: Error checking! */ | ||||
| 	Context; | ||||
| 	switch ((status = g_io_channel_write_chars(connection->iochannel, send_buffer, -1, &len, &error))) | ||||
| 	{ | ||||
| 		case G_IO_STATUS_ERROR: | ||||
| 			wmud_log_error("Error during g_io_channel_write_chars(): %s", error->message); | ||||
| 			break; | ||||
| 		case G_IO_STATUS_NORMAL: | ||||
| 			wmud_log_debug("Message sent"); | ||||
| 			break; | ||||
| 		case G_IO_STATUS_EOF: | ||||
| 			wmud_log_warning("EOF during g_io_channel_write_chars()???"); | ||||
| 			break; | ||||
| 		case G_IO_STATUS_AGAIN: | ||||
| 			wmud_log_warning("Resource temporarily unavailable while sending message to client"); | ||||
| 			break; | ||||
| 		default: | ||||
| 			wmud_log_error("Unknown return value from g_io_channel_write_chars()!"); | ||||
| 			break; | ||||
| 	} | ||||
| 	if (error != NULL) | ||||
| 	{ | ||||
| 		g_error_free(error); | ||||
| 		error = NULL; | ||||
| 	} | ||||
| 	Context g_free(send_buffer); | ||||
|  | ||||
| 	switch ((status = g_io_channel_flush(connection->iochannel, &error))) | ||||
| 	{ | ||||
| 		case G_IO_STATUS_ERROR: | ||||
| 			wmud_log_error("Error during g_io_channel_flush(): %s", error->message); | ||||
| 			break; | ||||
| 		case G_IO_STATUS_NORMAL: | ||||
| 			wmud_log_debug("IOChannel flushed"); | ||||
| 			break; | ||||
| 		case G_IO_STATUS_EOF: | ||||
| 			wmud_log_warning("EOF during g_io_channel_flush()???"); | ||||
| 			break; | ||||
| 		case G_IO_STATUS_AGAIN: | ||||
| 			wmud_log_warning("Resource temporarily unavailable while sending message to client"); | ||||
| 			break; | ||||
| 		default: | ||||
| 			wmud_log_error("Unknown return value from g_io_channel_flush()!"); | ||||
| 			break; | ||||
| 	} | ||||
|  | ||||
| 	if (error != NULL) | ||||
| 	{ | ||||
| 		g_error_free(error); | ||||
| 		error = NULL; | ||||
| 	} | ||||
| 	Context; | ||||
| } | ||||
|  | ||||
| const gchar * | ||||
| wmud_connection_get_linebreak(GConn *connection) | ||||
| { | ||||
| 	wMUDSession *session; | ||||
|  | ||||
| 	Context session = wmud_session_for_connection(connection); | ||||
|  | ||||
| 	if (session) | ||||
| 	{ | ||||
| 		switch (wmud_session_get_session_type(session)) | ||||
| 		{ | ||||
| 			case WMUD_SESSION_TYPE_TELNET: | ||||
| 				Context return "\r\n"; | ||||
| 				break; | ||||
| 			case WMUD_SESSION_TYPE_IRC: | ||||
| 				Context return "\r\n"; | ||||
| 				break; | ||||
| 			default: | ||||
| 				wmud_log_warning("Looling for linebreak for unknown session type"); | ||||
| 				return ""; | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		Context; | ||||
| 	} | ||||
|  | ||||
| 	return ""; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * _wmud_accept_telnet: | ||||
|  * @server: the #GServer object that has an incoming connection | ||||
|  * @connection: The #GConn created to hold the new connection | ||||
|  * @user_data: user data arrived with this function call. Currently it is not used | ||||
|  * | ||||
|  * Callback function which gets called whenever a new connection arrived on a server socket | ||||
|  */ | ||||
| static void | ||||
| _wmud_accept_telnet(GServer *server, GConn *connection, gpointer user_data) | ||||
| { | ||||
| 	wMUDConfigurationInterface *interface = (wMUDConfigurationInterface *)user_data; | ||||
| 	/* If the connection is not created for some reason, log an error and return */ | ||||
| 	if (connection == NULL) | ||||
| 	{ | ||||
| 		wmud_log_error("Error while accepting connection"); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	/* TODO: Disconnect if the IP is banned */ | ||||
|  | ||||
| 	/* Log a message that a new connection has arrived */ | ||||
| 	wmud_log_info("Accepted telnet connection from [%s]", gnet_inetaddr_get_canonical_name(connection->inetaddr)); | ||||
|  | ||||
| 	/* Set the parameters of this connection */ | ||||
| 	/* The connection should be buffered, so it is easier to handle */ | ||||
| 	g_io_channel_set_buffered(connection->iochannel, TRUE); | ||||
| 	/* The function to call, whenever an event occurs */ | ||||
| 	gnet_conn_set_callback(connection, _wmud_telnet_event, NULL); | ||||
| 	/* Watch for readable events */ | ||||
| 	gnet_conn_set_watch_readable(connection, TRUE); | ||||
| 	/* Timeout interval */ | ||||
| 	gnet_conn_timeout(connection, interface->timeout * 1000); | ||||
|  | ||||
| 	Context; | ||||
|  | ||||
| 	if (!wmud_new_session(connection, WMUD_SESSION_TYPE_TELNET)) | ||||
| 	{ | ||||
| 		Context; | ||||
| 		g_io_channel_write_chars(connection->iochannel, "Unable to create a session for you. If you experience this problem for more than once, please contact us!", -1, NULL, NULL); | ||||
| 		gnet_conn_disconnect(connection); | ||||
| 	} | ||||
|  | ||||
| 	Context; | ||||
| } | ||||
|  | ||||
| static void | ||||
| _wmud_accept_irc(GServer *server, GConn *connection, gpointer user_data) | ||||
| { | ||||
| 	wMUDConfigurationInterface *interface = (wMUDConfigurationInterface *)user_data; | ||||
|  | ||||
| 	if (connection == NULL) | ||||
| 	{ | ||||
| 		wmud_log_error("Error while accepting connection"); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	/* TODO: Disconnect if the IP is banned */ | ||||
|  | ||||
| 	/* Log a message that a new connection has arrived */ | ||||
| 	wmud_log_info("Accepted IRC connection from [%s]", gnet_inetaddr_get_canonical_name(connection->inetaddr)); | ||||
|  | ||||
| 	/* Set the parameters of this connection */ | ||||
| 	/* The connection should be buffered, so it is easier to handle */ | ||||
| 	g_io_channel_set_buffered(connection->iochannel, TRUE); | ||||
| 	/* The function to call, whenever an event occurs */ | ||||
| 	gnet_conn_set_callback(connection, _wmud_irc_event, NULL); | ||||
| 	/* Watch for readable events */ | ||||
| 	gnet_conn_set_watch_readable(connection, TRUE); | ||||
| 	/* Timeout interval */ | ||||
| 	gnet_conn_timeout(connection, interface->timeout * 1000); | ||||
|  | ||||
| 	Context; | ||||
|  | ||||
| 	if (!wmud_new_session(connection, WMUD_SESSION_TYPE_TELNET)) | ||||
| 	{ | ||||
| 		Context; | ||||
| 		g_io_channel_write_chars(connection->iochannel, "Unable to create a session for you. If you experience this problem for more than once, please contact us!", -1, NULL, NULL); | ||||
| 		gnet_conn_disconnect(connection); | ||||
| 	} | ||||
|  | ||||
| 	Context; | ||||
| } | ||||
|  | ||||
| static void | ||||
| _wmud_create_interface(gpointer data, gpointer user_data) | ||||
| { | ||||
| 	GServer *server; | ||||
| 	wMUDConfigurationInterface *interface = (wMUDConfigurationInterface *)data; | ||||
|  | ||||
| 	wmud_log_debug("Creating new interface '%s'", interface->name); | ||||
| 	switch (interface->type) | ||||
| 	{ | ||||
| 		case WMUD_SESSION_TYPE_TELNET: | ||||
| 			server = gnet_server_new(interface->inetaddr, gnet_inetaddr_get_port(interface->inetaddr), _wmud_accept_telnet, interface); | ||||
| 			_wmud_active_interfaces = g_slist_append(_wmud_active_interfaces, (gpointer)server); | ||||
| 			break; | ||||
| 		case WMUD_SESSION_TYPE_IRC: | ||||
| 			server = gnet_server_new(interface->inetaddr, gnet_inetaddr_get_port(interface->inetaddr), _wmud_accept_irc, interface); | ||||
| 			_wmud_active_interfaces = g_slist_append(_wmud_active_interfaces, (gpointer)server); | ||||
| 			break; | ||||
| 		default: | ||||
| 			wmud_log_error("Unknown type of interface!"); | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void | ||||
| wmud_connection_disconnect(GConn *connection) | ||||
| { | ||||
| 		gnet_conn_disconnect(connection); | ||||
| } | ||||
|  | ||||
| gpointer | ||||
| wmud_networking_thread(gpointer data) | ||||
| { | ||||
| 	wMUDThreadData *thread_data = (wMUDThreadData *)data; | ||||
|  | ||||
| 	Context; | ||||
| 	wmud_log_info("Initializing network layer..."); | ||||
|  | ||||
| 	/* g_main_context_get_thread_default() is only available since GLib 2.22; | ||||
| 	 * use g_main_context_new() otherwise | ||||
| 	 */ | ||||
| #if (((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION >= 22)) || (GLIB_MAJOR_VERSION > 2)) | ||||
| 	thread_data->main_context = g_main_context_get_thread_default(); | ||||
| #else | ||||
| 	thread_data->main_context = g_main_context_new(); | ||||
| #endif | ||||
| 	thread_data->main_loop = g_main_loop_new(thread_data->main_context, FALSE); | ||||
|  | ||||
| 	/* Do the real initialization work here */ | ||||
|  | ||||
| 	Context g_slist_foreach(wmud_configuration->interfaces, _wmud_create_interface, NULL); | ||||
|  | ||||
| 	/* End of initialization */ | ||||
|  | ||||
| 	wmud_log_info("Network layer initialized"); | ||||
|  | ||||
| 	Context; | ||||
| 	thread_data->running = TRUE; | ||||
| 	g_main_loop_run(thread_data->main_loop); | ||||
|  | ||||
| 	wmud_log_info("Network layer shutting down"); | ||||
|  | ||||
| 	wmud_destroy_all_sessions("Server is shutting down."); | ||||
|  | ||||
| 	g_main_loop_unref(thread_data->main_loop); | ||||
| 	thread_data->main_loop = NULL; | ||||
|  | ||||
| 	thread_data->running = FALSE; | ||||
|  | ||||
| 	Context; | ||||
|  | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
							
								
								
									
										13
									
								
								src/networking.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/networking.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| #ifndef __WMUD_CORE_NETWORKING_H__ | ||||
| #define __WMUD_CORE_NETWORKING_H__ | ||||
|  | ||||
| #include <glib.h> | ||||
| #include <gnet.h> | ||||
|  | ||||
| gpointer wmud_networking_thread(gpointer data); | ||||
| void wmud_connection_disconnect(GConn *connection); | ||||
| void wmud_connection_send(GConn *connection, gchar *fmt, ...); | ||||
| const gchar *wmud_connection_get_linebreak(GConn *connection); | ||||
|  | ||||
| #endif /* __WMUD_CORE_NETWORKING_H__ */ | ||||
|  | ||||
							
								
								
									
										15
									
								
								src/protocols-module.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/protocols-module.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| #ifndef __WMUD_MODULE_PROTOCOLS_H__ | ||||
| #define __WMUD_MODULE_PROTOCOLS_H__ | ||||
|  | ||||
| #include <glib.h> | ||||
|  | ||||
| enum { | ||||
| 	WMUD_ERROR_PROTOCOL_OK, | ||||
| 	WMUD_ERROR_PROTOCOL_EXISTS | ||||
| }; | ||||
|  | ||||
| #define WMUD_ERROR_PROTOCOL g_quark_from_string("WMUD PROTOCOL ERROR") | ||||
| GQuark wmud_register_protocol(gchar *name, GError **error); | ||||
|  | ||||
| #endif /* __WMUD_MODULE_PROTOCOLS_H__ */ | ||||
|  | ||||
							
								
								
									
										32
									
								
								src/protocols.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/protocols.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| #include <glib.h> | ||||
|  | ||||
| #include "protocols.h" | ||||
|  | ||||
| guint wmud_current_protocol_number = 0; | ||||
|  | ||||
| GQuark | ||||
| wmud_register_protocol(gchar *name, GError **error) | ||||
| { | ||||
| 	gchar *full_protocol_name; | ||||
|  | ||||
| 	if (name == NULL) | ||||
| 	{ | ||||
| 		return g_quark_from_string(NULL); | ||||
| 	} | ||||
|  | ||||
| 	full_protocol_name = g_strdup_printf("WMUD PROTO %s", name); | ||||
|  | ||||
| 	if (g_quark_try_string(full_protocol_name) != 0) | ||||
| 	{ | ||||
| 		/* Quark already exists => protocol is already registered */ | ||||
| 		if (*error) | ||||
| 		{ | ||||
| 			*error = g_error_new(WMUD_ERROR_PROTOCOL, WMUD_ERROR_PROTOCOL_EXISTS, "Protocol %s is already registered", name); | ||||
| 		} | ||||
|  | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	return g_quark_from_string(full_protocol_name); | ||||
| } | ||||
|  | ||||
							
								
								
									
										9
									
								
								src/protocols.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/protocols.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| #ifndef __WMUD_CORE_PROTOCOLS_H__ | ||||
| #define __WMUD_CORE_PROTOCOLS_H__ | ||||
|  | ||||
| #include <glib.h> | ||||
|  | ||||
| #include "protocols-module.h" | ||||
|  | ||||
| #endif /* __WMUD_CORE_PROTOCOLS_H__ */ | ||||
|  | ||||
							
								
								
									
										101
									
								
								src/sessions.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								src/sessions.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| #include <glib.h> | ||||
| #include <gnet.h> | ||||
|  | ||||
| #include "wmud.h" | ||||
| #include "sessions.h" | ||||
| #include "networking.h" | ||||
| #include "logger.h" | ||||
|  | ||||
| #include "wmud-session.h" | ||||
|  | ||||
| GSList *wmud_session_list = NULL; | ||||
|  | ||||
| gboolean | ||||
| wmud_new_session(GConn *connection, wMUDSessionType type) | ||||
| { | ||||
| 	wMUDSession *session; | ||||
|  | ||||
| 	Context; | ||||
|  | ||||
| 	if ((session = wmud_session_new_with_connection(connection)) == NULL) | ||||
| 	{ | ||||
| 		return FALSE; | ||||
| 	} | ||||
|  | ||||
| 	Context wmud_session_set_session_type(session, type); | ||||
|  | ||||
| 	Context; | ||||
|  | ||||
| 	wmud_session_list = g_slist_append(wmud_session_list, session); | ||||
|  | ||||
| 	Context; | ||||
|  | ||||
| 	return TRUE; | ||||
| } | ||||
|  | ||||
| static gint | ||||
| _wmud_find_session_with_connection(gconstpointer list_element, gconstpointer connection) | ||||
| { | ||||
| 	wMUDSession *session = (wMUDSession *)list_element; | ||||
| 	GConn *conn = (GConn *)connection; | ||||
|  | ||||
| 	g_assert(WMUD_IS_SESSION(list_element)); | ||||
|  | ||||
| 	Context return (wmud_session_has_connection(session, conn)) ? 0 : 1; | ||||
| } | ||||
|  | ||||
| wMUDSession * | ||||
| wmud_session_for_connection(GConn *connection) | ||||
| { | ||||
| 	GSList *temp; | ||||
|  | ||||
| 	Context temp = g_slist_find_custom(wmud_session_list, connection, _wmud_find_session_with_connection); | ||||
|  | ||||
| 	if (temp) | ||||
| 	{ | ||||
| 		return temp->data; | ||||
| 	} | ||||
|  | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| void | ||||
| wmud_finish_session(wMUDSession *session, gchar *message) | ||||
| { | ||||
| 	if ((session == NULL) || (!WMUD_IS_SESSION(session))) | ||||
| 	{ | ||||
| 		return; | ||||
| 	} | ||||
| 	GConn *connection = wmud_session_get_connection(session); | ||||
|  | ||||
| 	if (connection) | ||||
| 	{ | ||||
| 		wmud_log_debug("Destroying session with connection"); | ||||
| 		if (message) | ||||
| 		{ | ||||
| 			wmud_connection_send(connection, message); | ||||
| 		} | ||||
| 		wmud_connection_disconnect(connection); | ||||
| 		wmud_session_set_connection(session, NULL); | ||||
| 	} | ||||
|  | ||||
| 	wmud_session_list = g_slist_remove_all(wmud_session_list, session); | ||||
| 	wmud_session_unref(session); | ||||
| } | ||||
|  | ||||
| static void | ||||
| _wmud_destroy_session(gpointer sess, gpointer msg) | ||||
| { | ||||
| 	wMUDSession *session = (wMUDSession *)sess; | ||||
| 	gchar *message = (gchar *)msg; | ||||
|  | ||||
| 	wmud_log_debug("Shutting down session %lx", sess); | ||||
| 	wmud_finish_session(session, message); | ||||
| } | ||||
|  | ||||
| void | ||||
| wmud_destroy_all_sessions(gchar *message) | ||||
| { | ||||
| 	g_slist_foreach(wmud_session_list, _wmud_destroy_session, message); | ||||
| } | ||||
|  | ||||
							
								
								
									
										17
									
								
								src/sessions.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/sessions.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| #ifndef __WMUD_CORE_SESSIONS_H__ | ||||
| #define __WMUD_CORE_SESSIONS_H__ | ||||
|  | ||||
| #include <glib.h> | ||||
| #include <gnet.h> | ||||
|  | ||||
| #include "wmud-session.h" | ||||
|  | ||||
| extern GSList *wmud_session_list; | ||||
|  | ||||
| gboolean wmud_new_session(GConn *connection, wMUDSessionType type); | ||||
| wMUDSession *wmud_session_for_connection(GConn *connection); | ||||
| void wmud_finish_session(wMUDSession *session, gchar *message); | ||||
| void wmud_destroy_all_sessions(gchar *message); | ||||
|  | ||||
| #endif /* __WMUD_CORE_SESSIONS_H__ */ | ||||
|  | ||||
							
								
								
									
										27
									
								
								src/wmud-module.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/wmud-module.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| #ifndef __WMUD_MODULE_WMUD_H__ | ||||
| #define __WMUD_MODULE_WMUD_H__ | ||||
|  | ||||
| #include <glib.h> | ||||
|  | ||||
| #include "protocols-module.h" | ||||
| #include "configfile-module.h" | ||||
| #include "logger-module.h" | ||||
|  | ||||
| enum _wMUDCallableNum { | ||||
| 	WMUD_CALLABLE_WMUD_LOG, | ||||
| #ifdef DEBUG | ||||
| 	WMUD_CALLABLE_WMUD_PRINT_CONTEXT, | ||||
| #endif /* DEBUG */ | ||||
| 	WMUD_CALLABLE_LAST | ||||
| }; | ||||
|  | ||||
| extern gpointer wMUDCallables[]; | ||||
|  | ||||
| #if DEBUG | ||||
| #define Context wmud_print_context(__FILE__, __LINE__); | ||||
| #else | ||||
| #define Context | ||||
| #endif | ||||
|  | ||||
| #endif /* __WMUD_MODULE_WMUD_H__ */ | ||||
|  | ||||
							
								
								
									
										244
									
								
								src/wmud.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								src/wmud.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,244 @@ | ||||
| #include <glib.h> | ||||
| #include <glib-object.h> | ||||
| #include <gnet.h> | ||||
| #include <signal.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/types.h> | ||||
| #include <dirent.h> | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <libgnomevfs/gnome-vfs.h> | ||||
|  | ||||
| #ifdef HAVE_CONFIG_H | ||||
| #include "config.h" | ||||
| #endif /* HAVE_CONFIG_H */ | ||||
|  | ||||
| #include "wmud.h" | ||||
| #include "logger.h" | ||||
| #include "ansi.h" | ||||
| #include "networking.h" | ||||
| #include "world.h" | ||||
| #include "configfile.h" | ||||
| #include "chat.h" | ||||
| #include "modules.h" | ||||
|  | ||||
| /* TODO: Make this configurable via configure, and/or countable based on sysconfdir */ | ||||
| #define DEFAULT_CONFIGFILE "/home/polesz/Projektek/wMUD/data/wmud.conf" | ||||
|  | ||||
| GSList *wmud_running_threads = NULL; | ||||
| gchar *wmud_option_configfile = NULL; | ||||
| wMUDConfiguration *wmud_configuration = NULL; | ||||
| GMainLoop *wmud_main_loop = NULL; | ||||
| gboolean wmud_is_running = FALSE; | ||||
|  | ||||
| pid_t wmud_pid; | ||||
|  | ||||
| static GOptionEntry option_entries[] = { | ||||
| 	{ "configfile", 'c', G_OPTION_FLAG_FILENAME, G_OPTION_ARG_FILENAME, &wmud_option_configfile, "Configuration file to parse instead of the default one", "filename" }, | ||||
| 	{ NULL }, | ||||
| }; | ||||
|  | ||||
| #if DEBUG | ||||
| void | ||||
| wmud_print_context(char *filename, int linenum) | ||||
| { | ||||
| 	fprintf(stderr, "\x1b[34m\x1b[1m[DEBUG CONTEXT] %s:%d\x1b[0m\n", filename, linenum); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| void | ||||
| _fatal_signal_handler(int signum) | ||||
| { | ||||
| 	fprintf(stderr, "Segmentation fault.\n"); | ||||
|  | ||||
| 	exit(1); | ||||
| } | ||||
|  | ||||
| void | ||||
| _terminating_signal_handler(int signum) | ||||
| { | ||||
| 	switch (signum) | ||||
| 	{ | ||||
| 		case SIGINT: | ||||
| 			wmud_shutdown(); | ||||
| 			break; | ||||
| 		default: | ||||
| 			return; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void | ||||
| _wmud_shutdown_thread(gpointer data, gpointer user_data) | ||||
| { | ||||
| 	wMUDThreadData *thread = (wMUDThreadData *)data; | ||||
|  | ||||
| 	wmud_log_debug("Shutting down %s thread", thread->name); | ||||
| 	if (thread->main_loop) | ||||
| 	{ | ||||
| 		Context; | ||||
| 		wmud_log_debug("Stopping %s thread's main loop", thread->name); | ||||
| 		g_main_loop_quit(thread->main_loop); | ||||
| 		while (1) | ||||
| 		{ | ||||
| 			if (!thread->running) | ||||
| 			{ | ||||
| 				break; | ||||
| 			} | ||||
| 			usleep(200); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	Context; | ||||
| } | ||||
|  | ||||
| void | ||||
| wmud_shutdown(void) | ||||
| { | ||||
| 	wmud_log_info("Shutting down..."); | ||||
|  | ||||
| 	Context g_slist_foreach(wmud_running_threads, _wmud_shutdown_thread, NULL); | ||||
|  | ||||
| 	if (wmud_main_loop) | ||||
| 	{ | ||||
| 		Context g_main_loop_quit(wmud_main_loop); | ||||
| 		g_main_loop_unref(wmud_main_loop); | ||||
| 		wmud_main_loop = NULL; | ||||
| 	} | ||||
|  | ||||
| 	wmud_is_running = FALSE; | ||||
|  | ||||
| 	Context wmud_log_info("Shutdown complete"); | ||||
| } | ||||
|  | ||||
| void | ||||
| wmud_parse_options(gint *argc, gchar ***argv) | ||||
| { | ||||
| 	GOptionContext *options_context; | ||||
| 	GError *error = NULL; | ||||
|  | ||||
| 	options_context = g_option_context_new("wMUD server"); | ||||
| 	g_option_context_add_main_entries(options_context, option_entries, NULL); | ||||
|  | ||||
| 	if (!g_option_context_parse(options_context, argc, argv, &error)) | ||||
| 	{ | ||||
| 		g_log(NULL, G_LOG_FLAG_FATAL | G_LOG_LEVEL_ERROR, "Failed parsing options: %s\n", error->message); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static GThread * | ||||
| _new_thread(GThreadFunc thread_func, GError **error, gchar *thread_name, gboolean fatal_if_fail) | ||||
| { | ||||
| 	GThread *thread; | ||||
| 	wMUDThreadData *thread_data; | ||||
|  | ||||
| 	/* Create and initialize thread data */ | ||||
| 	thread_data = g_new0(wMUDThreadData, 1); | ||||
|  | ||||
| 	thread_data->main_loop = NULL; | ||||
| 	thread_data->main_context = NULL; | ||||
| 	thread_data->thread = NULL; | ||||
| 	thread_data->name = g_strdup(thread_name); | ||||
| 	thread_data->running = FALSE; | ||||
|  | ||||
| 	if ((thread = g_thread_create(thread_func, thread_data, FALSE, error)) == NULL) | ||||
| 	{ | ||||
| 		wmud_log_error("Unable to start %s thread!", thread_name); | ||||
|  | ||||
| 		if (fatal_if_fail) | ||||
| 		{ | ||||
| 			wmud_shutdown(); | ||||
| 		} | ||||
| 		g_free(thread_data); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		thread_data->thread = thread; | ||||
| 		wmud_running_threads = g_slist_append(wmud_running_threads, thread_data); | ||||
| 	} | ||||
|  | ||||
| 	return thread; | ||||
| } | ||||
|  | ||||
| int | ||||
| main(int argc, char **argv) | ||||
| { | ||||
| 	GError *error; | ||||
| 	GThread *thread; | ||||
| 	struct sigaction signal_action; | ||||
|  | ||||
| 	wmud_pid = getpid(); | ||||
|  | ||||
| 	wmud_log_info("wMUD v%s starting up", PACKAGE_VERSION); | ||||
|  | ||||
| 	signal_action.sa_handler = _fatal_signal_handler; | ||||
| 	sigemptyset(&signal_action.sa_mask); | ||||
| 	signal_action.sa_flags = 0; | ||||
| 	sigaction(SIGSEGV, &signal_action, NULL); | ||||
|  | ||||
| 	signal_action.sa_handler = _terminating_signal_handler; | ||||
| 	sigemptyset(&signal_action.sa_mask); | ||||
| 	signal_action.sa_flags = 0; | ||||
| 	sigaction(SIGINT, &signal_action, NULL); | ||||
|  | ||||
| 	Context g_type_init(); | ||||
| 	Context gnet_init(); | ||||
| 	gnome_vfs_init(); | ||||
|  | ||||
| 	Context wmud_parse_options(&argc, &argv); | ||||
|  | ||||
| 	Context; | ||||
|  | ||||
| 	/* TODO: Make this configurable via configure, and/or countable based on sysconfdir */ | ||||
| 	if (wmud_option_configfile == NULL) | ||||
| 	{ | ||||
| 		wmud_option_configfile = g_strdup(DEFAULT_CONFIGFILE); | ||||
| 	} | ||||
|  | ||||
| 	if (!wmud_configfile_read(wmud_option_configfile, &wmud_configuration, &error)) | ||||
| 	{ | ||||
| 		return 1; | ||||
| 	} | ||||
| 	if (wmud_configuration == NULL) | ||||
| 	{ | ||||
| 		return 1; | ||||
| 	} | ||||
| 	Context g_free(wmud_option_configfile); | ||||
| 	Context wmud_fill_callable_table(); | ||||
| 	Context wmud_load_config_modules(wmud_configuration); | ||||
| 	return 0; | ||||
|  | ||||
| 	if (wmud_logger_init(wmud_configuration)) | ||||
| 	{ | ||||
| 		wmud_log_debug("Logger initialized"); | ||||
| 		Context if (!g_thread_supported()) | ||||
| 		{ | ||||
| 			g_thread_init(NULL); | ||||
| 		} | ||||
|  | ||||
| 		Context thread = _new_thread(wmud_networking_thread, &error, "networking", TRUE); | ||||
| 		Context thread = _new_thread(wmud_world_thread, &error, "world", TRUE); | ||||
| 		Context thread = _new_thread(wmud_chat_thread, &error, "chat", TRUE); | ||||
| 		Context; | ||||
|  | ||||
| 		wmud_main_loop = g_main_loop_new(NULL, FALSE); | ||||
|  | ||||
| 		wmud_is_running = TRUE; | ||||
|  | ||||
| 		g_main_loop_run(wmud_main_loop); | ||||
| 	} | ||||
|  | ||||
| 	wmud_configuration_free(&wmud_configuration); | ||||
|  | ||||
| 	if (wmud_is_running) | ||||
| 	{ | ||||
| 		wmud_shutdown(); | ||||
| 	} | ||||
|  | ||||
| 	Context gnome_vfs_shutdown(); | ||||
|  | ||||
| 	wmud_log_debug("Good bye..."); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										32
									
								
								src/wmud.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/wmud.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| #ifndef __WMUD_CORE_WMUD_H__ | ||||
| #define __WMUD_CODE_WMUD_H__ | ||||
|  | ||||
| #include <glib.h> | ||||
|  | ||||
| /* DEBUG is defined in config.h, if present. | ||||
|  * DEBUG is needed for Context, so let's include config.h here. | ||||
|  */ | ||||
| #ifdef HAVE_CONFIG_H | ||||
| #include "config.h" | ||||
| #endif /* HAVE_CONFIG_H */ | ||||
|  | ||||
| #include <sys/types.h> | ||||
|  | ||||
| typedef struct _wMUDThreadData | ||||
| { | ||||
| 	GMainContext *main_context; | ||||
| 	GMainLoop *main_loop; | ||||
| 	GThread *thread; | ||||
| 	gchar *name; | ||||
| 	gboolean running; | ||||
| } wMUDThreadData; | ||||
|  | ||||
| extern pid_t wmud_pid; | ||||
|  | ||||
| void wmud_shutdown(void); | ||||
| #ifdef DEBUG | ||||
| void wmud_print_context(char *filename, int linenum); | ||||
| #endif /* DEBUG */ | ||||
|  | ||||
| #endif /* __WMUD_CORE_WMUD_H__ */ | ||||
|  | ||||
							
								
								
									
										47
									
								
								src/world.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/world.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| #include <glib.h> | ||||
|  | ||||
| #include "wmud-world.h" | ||||
|  | ||||
| #include "wmud.h" | ||||
| #include "logger.h" | ||||
|  | ||||
| gpointer | ||||
| wmud_world_thread(gpointer data) | ||||
| { | ||||
| 	wMUDWorld *world; | ||||
|  | ||||
| 	wMUDThreadData *thread_data = (wMUDThreadData *)data; | ||||
|  | ||||
| 	wmud_log_info("Initializing world..."); | ||||
|  | ||||
| 	/* g_main_context_get_thread_default() is only available since GLib 2.22; | ||||
| 	 * use g_main_context_new() otherwise | ||||
| 	 */ | ||||
| #if (((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION >= 22)) || (GLIB_MAJOR_VERSION > 2)) | ||||
| 	thread_data->main_context = g_main_context_get_thread_default(); | ||||
| #else | ||||
| 	thread_data->main_context = g_main_context_new(); | ||||
| #endif | ||||
| 	thread_data->main_loop = g_main_loop_new(thread_data->main_context, FALSE); | ||||
|  | ||||
| 	/* TODO: Do the real initialization here */ | ||||
|  | ||||
| 	world = wmud_world_new(); | ||||
|  | ||||
| 	wmud_log_info("World initialized"); | ||||
|  | ||||
| 	thread_data->running = TRUE; | ||||
|  | ||||
| 	g_main_loop_run(thread_data->main_loop); | ||||
|  | ||||
| 	g_main_loop_unref(thread_data->main_loop); | ||||
|  | ||||
| 	thread_data->main_loop = NULL; | ||||
|  | ||||
| 	wmud_log_info("World layer shutting down..."); | ||||
|  | ||||
| 	thread_data->running = FALSE; | ||||
|  | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
							
								
								
									
										7
									
								
								src/world.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/world.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| #ifndef __WMUD_CORE_WORLD_H__ | ||||
| #define __WMUD_CORE_WORLD_H__ | ||||
|  | ||||
| gpointer wmud_world_thread(gpointer data); | ||||
|  | ||||
| #endif /* __WMUD_CORE_WORLD_H__ */ | ||||
|  | ||||
		Reference in New Issue
	
	Block a user