Initial import
This commit is contained in:
commit
2f36baf323
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__ */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user