new file mode 100644
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,24 @@
+MCBOT INSTALLATION
+------------------
+
+STEP 1)
+ REGISTER YOUR BOT TO AN IRC SERVER
+ EDIT /var/lib/nobody/.mcbotrc
+
+STEP 2)
+ FIX PERMISSIONS AND HIDE YOUR REGISTRATION DATA
+ chown -R nobody:nogroup /var/lib/nobody
+ chmod 775 /var/lib/nobody
+ chmod 600 /var/lib/nobody/.mcbotrc
+
+STEP 3)
+ /etc/init.d/mcbot start
+
+STEP 4)
+ dbtool -a -k mcbot.cgi -v http://your.domain.com/cgi-bin/mcbot.cgi
+ dbtool -a -k mcbot.user -v <admin nick> # mbroeker
+ dbtool -a -k mcbot.email -v <admin-hostmask> # pppool.de
+
+STEP 5)
+ Check your locale settings in /etc/init.d/mcbot
+ LANGUAGE="de_DE.UTF-8" or LANGUAGE="en_US.UTF-8" for example
new file mode 100644
--- /dev/null
+++ b/TODO
@@ -0,0 +1,18 @@
+#
+# Project : mcbot
+#
+
+Known Bugs:
+ * no known bugs :)
+ * PRIVMSG for n=some@unaffiliated/users
+
+Todo:
+ * UTF-8 aware Character-Encoding
+ * Dynamic Loading of plugins with dlopen
+ * implementation of some fun stuff
+
+Author:
+ * Markus Broeker mbroeker@largo.homelinux.org
+
+Comments:
+ * scanner/parser rewritten
new file mode 100644
--- /dev/null
+++ b/config/.mcbotrc
@@ -0,0 +1,10 @@
+#
+# This is a simple ~/.mcbotrc
+# NO SPACING, PLEASE !!
+#
+NICK:test
+PASSWORD:test
+SERVER:irc.freenode.net
+PORT:6667
+CHANNEL:#test
+TOPIC:[:test:] Support Channel || ENTER !help for help || Source: http://largo.homelinux.org/svn/c/mcbot/trunk
new file mode 100644
--- /dev/null
+++ b/config/.screenrc
@@ -0,0 +1,1 @@
+termcapinfo xterm|xterms|xs|rxvt ti@te@
new file mode 100644
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,9 @@
+mcbot (0.93-2) unstable; urgency=low
+
+ * Initial Release
+ * the location of mcbot.cgi is stored in the db
+ * never include malloc, use stdlib instead
+ * mcbot.email and mcbot.user holds the admin information
+ * Locale Settings changed to C
+
+ -- Markus Broeker <mbroeker@largo.homelinux.org> Sun, 27 Apr 2008 09:05:54 +0200
new file mode 100644
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1,1 @@
+5
new file mode 100644
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,12 @@
+Source: mcbot
+Section: net
+Priority: extra
+Maintainer: Markus Broeker <mbroeker@largo.homelinux.org>
+Build-Depends: debhelper (>= 5)
+Standards-Version: 3.7.2
+
+Package: mcbot
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: mcbot is an irc bot
+ mcbot is a small irc bot with a factoids database.
new file mode 100644
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,22 @@
+This package was debianized by Markus Broeker <mbroeker@largo.homelinux.org> on
+Tue, 25 Mar 2008 20:32:44 +0100.
+
+It was downloaded from http://largo.homelinux.org
+
+Upstream Author(s):
+
+ mbroeker@largo.homelinux.org
+
+Copyright:
+
+ mbroeker@largo.homelinux.org
+
+License:
+
+ GPL
+
+The Debian packaging is (C) 2008, Markus Broeker <mbroeker@largo.homelinux.org> and
+is licensed under the GPL, see `/usr/share/common-licenses/GPL'.
+
+# Please also look if there are files or directories which have a
+# different copyright/license attached and list them here.
new file mode 100644
--- /dev/null
+++ b/debian/dirs
@@ -0,0 +1,2 @@
+var/lib/nobody/data
+var/lib/nobody
new file mode 100644
--- /dev/null
+++ b/debian/docs
@@ -0,0 +1,1 @@
+TODO
new file mode 100644
--- /dev/null
+++ b/debian/postinst
@@ -0,0 +1,57 @@
+#!/bin/sh
+# postinst script for mcbot
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * <postinst> `configure' <most-recently-configured-version>
+# * <old-postinst> `abort-upgrade' <new version>
+# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+# <new-version>
+# * <postinst> `abort-remove'
+# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+# <failed-install-package> <version> `removing'
+# <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ configure)
+ if [ ! -f /var/lib/nobody/data/mcbot.dat ];
+ then
+ echo "Creating initial database in /var/lib/nobody/data";
+ dbtool -a -k 1 -v 1;
+ dbtool -d 1;
+ fi
+
+ if [ -f /var/lib/nobody/.mcbotrc.dpkg-old ];
+ then
+ mv -f /var/lib/nobody/.mcbotrc.dpkg-old /var/lib/nobody/.mcbotrc;
+ fi
+
+ echo "Changing ownership in /var/lib/nobody"
+ usermod -s /bin/bash -d /var/lib/nobody nobody
+ chown -R nobody:nogroup /var/lib/nobody
+ echo "Setting permissions for /var/lib/nobody/.mcbotrc to 600"
+ chmod 600 /var/lib/nobody/.mcbotrc
+ echo "ENTER /etc/init.d/mcbot start after editing .mcbotrc"
+ ;;
+
+ abort-upgrade|abort-remove|abort-deconfigure)
+ ;;
+
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
new file mode 100644
--- /dev/null
+++ b/debian/postrm
@@ -0,0 +1,47 @@
+#!/bin/sh
+# postrm script for mcbot
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * <postrm> `remove'
+# * <postrm> `purge'
+# * <old-postrm> `upgrade' <new-version>
+# * <new-postrm> `failed-upgrade' <old-version>
+# * <new-postrm> `abort-install'
+# * <new-postrm> `abort-install' <old-version>
+# * <new-postrm> `abort-upgrade' <old-version>
+# * <disappearer's-postrm> `disappear' <overwriter>
+# <overwriter-version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ purge)
+ rm -rf /var/lib/nobody/data;
+ rm -f /var/lib/nobody/.mcbotrc;
+ rm -f /var/lib/nobody/mcbot-*.log;
+ usermod -d /nonexistent -s /bin/bash nobody
+ ;;
+
+ remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
+ usermod -d /nonexistent -s /bin/bash nobody
+ ;;
+
+ *)
+ echo "postrm called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
+
+
new file mode 100644
--- /dev/null
+++ b/debian/preinst
@@ -0,0 +1,46 @@
+#!/bin/sh
+# preinst script for mcbot
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * <new-preinst> `install'
+# * <new-preinst> `install' <old-version>
+# * <new-preinst> `upgrade' <old-version>
+# * <old-preinst> `abort-upgrade' <new-version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ install|upgrade)
+ if [ -x /etc/init.d/mcbot ];
+ then
+ /etc/init.d/mcbot stop;
+ fi
+
+ if [ -f /var/lib/nobody/.mcbotrc ];
+ then
+ cp -f /var/lib/nobody/.mcbotrc /var/lib/nobody/.mcbotrc.dpkg-old
+ fi
+ ;;
+
+ abort-upgrade)
+ ;;
+
+ *)
+ echo "preinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
+
+
new file mode 100755
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,91 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+
+
+
+configure: configure-stamp
+configure-stamp:
+ dh_testdir
+ # Add here commands to configure the package.
+
+ cmake src/
+ touch configure-stamp
+
+
+build: build-stamp
+
+build-stamp: configure-stamp
+ dh_testdir
+
+ # Add here commands to compile the package.
+ $(MAKE)
+ #docbook-to-man debian/mcbot.sgml > mcbot.1
+
+ touch $@
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp configure-stamp
+
+ # Add here commands to clean up after the build process.
+ if [ -f Makefile ]; then $(MAKE) clean; fi
+ rm -rf Makefile CMake* install* mcbot dbtool cmake_install.cmake
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+ # Add here commands to install the package into debian/mcbot.
+ $(MAKE) DESTDIR=$(CURDIR)/debian/mcbot install
+ cp config/.mcbotrc debian/mcbot/var/lib/nobody/
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+ dh_installchangelogs
+ dh_installdocs
+ dh_installexamples
+# dh_install
+# dh_installmenu
+# dh_installdebconf
+# dh_installlogrotate
+# dh_installemacsen
+# dh_installpam
+# dh_installmime
+# dh_python
+# dh_installinit
+# dh_installcron
+# dh_installinfo
+ dh_installman
+ dh_link
+ dh_strip
+ dh_compress
+ dh_fixperms
+# dh_perl
+# dh_makeshlibs
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
new file mode 100644
--- /dev/null
+++ b/include/config.h
@@ -0,0 +1,23 @@
+/**
+ * $Id: config.h 51 2008-01-10 00:19:39Z mbroeker $
+ * $URL: http://localhost/svn/c/mcbot/trunk/include/config.h $
+ *
+ */
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+struct UserConfig {
+ char *nick;
+ char *pass;
+ char *server;
+ int port;
+ char *topic;
+ char *channel;
+};
+
+typedef struct UserConfig UC;
+
+int config (UC *, char *);
+
+#endif
new file mode 100644
--- /dev/null
+++ b/include/database.h
@@ -0,0 +1,16 @@
+/**
+ * $Id: database.h 46 2008-01-09 23:59:17Z mbroeker $
+ * $URL: http://localhost/svn/c/mcbot/trunk/include/database.h $
+ *
+ */
+
+#ifndef DATABASE_H
+#define DATABASE_H
+
+char *db_insert (char *, char *, char *, int);
+char *db_remove (char *, char *);
+char *db_lookup (char *, char *);
+char *db_list (char *);
+char *db_elements (char *);
+char *db_vaccuum (char *);
+#endif
new file mode 100644
--- /dev/null
+++ b/include/irc.h
@@ -0,0 +1,29 @@
+/**
+ * $Id: irc.h 51 2008-01-10 00:19:39Z mbroeker $
+ * $URL: http://localhost/svn/c/mcbot/trunk/include/irc.h $
+ *
+ */
+
+#ifndef IRC_H
+#define IRC_H
+
+#define IRC_GENERAL_ERROR -50
+#define IRC_LOGIN_ERROR -51
+#define IRC_CONNECT_ERROR -52
+
+struct Message {
+ FILE *stream;
+ char *nick;
+ char *user;
+ char *email;
+ char *command;
+ char *channel;
+ char *line;
+};
+
+typedef struct Message MSG;
+
+FILE *irc_connect (char *, unsigned int);
+int irc_login (FILE *, char *, char *);
+char *irc_parsemessage (const char *, MSG *);
+#endif
new file mode 100644
--- /dev/null
+++ b/include/mcbot.h
@@ -0,0 +1,19 @@
+/**
+ * $Id: mcbot.h 46 2008-01-09 23:59:17Z mbroeker $
+ * $URL: http://localhost/svn/c/mcbot/trunk/include/mcbot.h $
+ *
+ */
+
+#ifndef MCBOT_H
+#define MCBOT_H
+
+#ifndef VERSION
+#define VERSION 0.0
+#endif
+
+#ifndef IRC_H
+#include <irc.h>
+#endif
+
+char *parse (MSG *, short *);
+#endif
new file mode 100644
--- /dev/null
+++ b/locale/de/mcbot.po
@@ -0,0 +1,57 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-12-26 15:44+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Markus Broeker <mbroeker@largo.homelinux.org>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: parse.c:78
+msgid "Request cannot be performed"
+msgstr "Operation kann nicht durchgefuehrt werden"
+
+#: parse.c:94
+msgid "What's up"
+msgstr "Was ist los"
+
+#: parse.c:149
+msgid "I need more parameters to add"
+msgstr "Ich brauche zwei Parameter zum Anfuegen"
+
+#: parse.c:164
+msgid "I need more parameters to replace"
+msgstr "Ich brauche zwei Parameter zum Ersetzen"
+
+#: parse.c:177
+msgid "I need a key to delete"
+msgstr "Ich brauche einen Schluessel zum Loeschen"
+
+#: parse.c:195
+msgid "I need a key to lookup"
+msgstr "Ich brauche einen Parameter zum Aufsuchen"
+
+#: parse.c:214
+msgid "Autolearn enabled for channel"
+msgstr "Autolearn ist aktiviert im Channel"
+
+#: parse.c:220
+msgid "Autolearn disabled for channel"
+msgstr "Autolearn ist deaktiviert im Channel"
+
+#: parse.c:240
+msgid "Bye, have a nice day!"
+msgstr "Machts gut, ich brauch ne Pause!"
+
+#: parse.c:268
+msgid "It is"
+msgstr "Es ist"
new file mode 100755
--- /dev/null
+++ b/scripts/mcbot.cgi
@@ -0,0 +1,32 @@
+#!/usr/bin/perl -W
+
+use strict;
+
+my $line;
+my $a;
+my $b;
+
+print "CONTENT-TYPE: text/html\n\n";
+
+print "<html>\n\t<head>\n\t\t<title>Factoids</title>\n\t</head>\n<body>\n";
+open(FD, "dbtool -l |") or die("Cannot open file");
+
+foreach $line(<FD>) {
+ ($a, $b) = split(/:/, $line, 2);
+ $a =~ s/^[\t ]+//; # skip blanks
+ $b =~ s/^[\t ]+//; # skip blanks
+ $b =~ s/[\n]+//; # for html source :)
+
+ if ($b) {
+ if($b =~ /^http/ ) {
+ print "$a - <a href=\"$b\">$b</a><br>";
+ } else {
+ print "$a - $b<br>";
+ }
+ }
+}
+
+print "\n<br>$a\n";
+
+print "</body></html>\n";
+close(FD);
new file mode 100755
--- /dev/null
+++ b/scripts/runbot
@@ -0,0 +1,56 @@
+#!/bin/sh
+
+BINARY="mcbot"
+DIRECTORY="/usr/local/sbin/"
+LANGUAGE="de_DE.UTF-8"
+
+[[ ! -x "${DIRECTORY}/${BINARY}" ]] && exit 0
+
+start() {
+ echo -n "Starting ${BINARY}"
+ su - nobody -c "LANG=$LANGUAGE ${DIRECTORY}/${BINARY} &>/var/lib/nobody/mcbot-`date "+%d-%m-%y"`.log &"
+ if [ "$?" == 0 ]; then
+ echo " [started]"
+ fi
+}
+
+stop() {
+ echo -n "Stopping ${BINARY}"
+ pid=`pidof ${BINARY}`
+ if [ "$pid" != "" ]; then
+ kill -TERM `pidof ${BINARY}`
+ sleep 5
+ fi
+ echo " [stopped]"
+}
+
+status() {
+ pid="`pidof ${BINARY}`"
+ if [ "$pid" != "" ]; then
+ echo "${BINARY} is started as ${pid}"
+ else
+ echo "${BINARY} is not running"
+ fi
+}
+
+case "$1" in
+ start)
+ start
+ ;;
+ stop)
+ stop
+ ;;
+ status)
+ status
+ ;;
+ restart)
+ echo "Restarting ${BINARY}"
+ stop
+ start
+ ;;
+ *)
+ echo "Usage: start|stop|restart|status"
+ ;;
+esac
+
+exit 0
new file mode 100644
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,37 @@
+PROJECT(mc_bot)
+
+# Project Settings
+SET(CMAKE_VERBOSE_MAKEFILE Off)
+SET(CMAKE_BUILD_TYPE Release)
+SET(CMAKE_C_FLAGS_RELEASE "-g -ggdb")
+
+# C-Definitions
+ADD_DEFINITIONS(-Wall -O2 -ansi -pedantic)
+ADD_DEFINITIONS(-D_XOPEN_SOURCE=500)
+ADD_DEFINITIONS(-DVERSION=0.91)
+
+# Includes
+INCLUDE_DIRECTORIES(../include)
+
+# Target Definitions
+ADD_EXECUTABLE(mcbot config.c database.c irc.c main.c parse.c)
+ADD_EXECUTABLE(dbtool database.c dbtool.c)
+
+# Install Rules
+INSTALL(TARGETS mcbot RUNTIME DESTINATION sbin)
+INSTALL(TARGETS dbtool RUNTIME DESTINATION bin)
+INSTALL(DIRECTORY ../locale/ DESTINATION /var/lib/nobody/data/locale)
+INSTALL(PROGRAMS ../scripts/runbot DESTINATION /etc/init.d/
+ RENAME mcbot)
+
+EXEC_PROGRAM(msgfmt ../locale ARGS -o de/LC_MESSAGES/mcbot.mo de/mcbot.po)
+
+# Search required libraries
+FIND_LIBRARY(GDBM_LIB NAMES gdbm
+ PATHS /usr/lib/ /usr/local/lib)
+IF (GDBM_LIB)
+ TARGET_LINK_LIBRARIES(mcbot ${GDBM_LIB})
+ TARGET_LINK_LIBRARIES(dbtool ${GDBM_LIB})
+ELSE(GDBM_LIB)
+ MESSAGE("YOU NEED TO INSTALL libgdbm-dev")
+ENDIF (GDBM_LIB)
new file mode 100644
--- /dev/null
+++ b/src/config.c
@@ -0,0 +1,110 @@
+/**
+ * $Id: config.c 51 2008-01-10 00:19:39Z mbroeker $
+ * $URL: http://localhost/svn/c/mcbot/trunk/src/config.c $
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <config.h>
+
+const
+char *CONFIG_OPTIONS[] = {
+ "NICK", "PASSWORD", "SERVER", "PORT",
+ "CHANNEL", "TOPIC",
+ NULL
+};
+
+int config (UC * uc, char *fname)
+{
+ FILE *f;
+ char buffer[513];
+ static char **line;
+ char *token;
+ char *value;
+ int i = 0;
+
+ if ((f = fopen (fname, "r")) == NULL)
+ return -1;
+
+ while (CONFIG_OPTIONS[i] != NULL)
+ i++;
+
+ line = calloc (i, sizeof (char *));
+
+ /*
+ * We can easily provide default values ...
+ */
+ uc->nick = uc->pass = uc->server = uc->channel = uc->topic = 0;
+ uc->port = 6667;
+
+ fgets (buffer, 512, f);
+
+ token = buffer;
+
+ while (!feof (f)) {
+ /*
+ * eat trailing tabs
+ */
+ while (*token == '\t')
+ token++;
+
+ /*
+ * eat trailing whitespaces
+ */
+ while (*token == ' ')
+ token++;
+
+ token = strtok (token, ":");
+
+ if (token != NULL) {
+ value = strtok (NULL, "\n");
+ i = 0;
+ while (CONFIG_OPTIONS[i] != NULL) {
+ if (!strcmp (token, CONFIG_OPTIONS[i])) {
+ line[i] = malloc (strlen (value) + 1);
+ strncpy (line[i], value, strlen (value));
+ }
+ i++;
+ }
+ }
+ *buffer = 0;
+ fgets (buffer, 512, f);
+ }
+
+ if (fclose (f) != 0)
+ return -1;
+
+ i = 0;
+ while (CONFIG_OPTIONS[i] != NULL) {
+ if (line[i] != NULL)
+ switch (i) {
+ case 0: /* NICK */
+ uc->nick = line[i];
+ break;
+ case 1: /* PASSWORD */
+ uc->pass = line[i];
+ break;
+ case 2: /* SERVER */
+ uc->server = line[i];
+ break;
+ case 3: /* PORT */
+ uc->port = atoi (line[i]);
+ break;
+ case 4: /* CHANNEL */
+ uc->channel = line[i];
+ break;
+ case 5: /* TOPIC */
+ uc->topic = line[i];
+ break;
+ }
+ i++;
+ }
+
+ if (!(uc->nick && uc->pass && uc->server && uc->channel))
+ return -2;
+
+ return 0;
+}
new file mode 100644
--- /dev/null
+++ b/src/database.c
@@ -0,0 +1,150 @@
+/**
+ * $Id: database.c 108 2008-04-17 01:01:52Z mbroeker $
+ * $URL: http://localhost/svn/c/mcbot/trunk/src/database.c $
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gdbm.h>
+
+#include <database.h>
+
+char *db_insert (char *file_name, char *name, char *msg, int mode)
+{
+ GDBM_FILE dbf;
+ datum key;
+ datum content;
+ int ret;
+
+ if ((dbf = gdbm_open (file_name, 512, GDBM_WRCREAT, 0644, 0)) == NULL)
+ return "db_insert error";
+
+ key.dptr = name;
+ key.dsize = strlen (name) + 1;
+
+ content.dptr = msg;
+ content.dsize = strlen (msg) + 1;
+
+ if (mode)
+ ret = gdbm_store (dbf, key, content, GDBM_REPLACE);
+ else
+ ret = gdbm_store (dbf, key, content, GDBM_INSERT);
+
+ gdbm_close (dbf);
+
+ if (!ret)
+ return "Key added";
+
+ return "error: key not added";
+}
+
+char *db_remove (char *file_name, char *name)
+{
+ GDBM_FILE dbf;
+ datum key;
+ int ret;
+
+ if ((dbf = gdbm_open (file_name, 512, GDBM_WRITER, 0, 0)) == NULL)
+ return "db_remove error";
+
+ key.dptr = name;
+ key.dsize = strlen (name) + 1;
+
+ ret = gdbm_delete (dbf, key);
+
+ gdbm_close (dbf);
+
+ if (!ret)
+ return "Key removed";
+ return "error: key not removed";
+}
+
+char *db_lookup (char *file_name, char *entry)
+{
+ GDBM_FILE dbf;
+ datum content;
+ datum key;
+ static char msg[513];
+
+ if ((dbf = gdbm_open (file_name, 512, GDBM_READER, 0, 0)) == NULL)
+ return "db_lookup error";
+
+ key.dptr = entry;
+ key.dsize = strlen (entry) + 1;
+
+ content = gdbm_fetch (dbf, key);
+ if (content.dptr != NULL)
+ snprintf (msg, 512, "%s", content.dptr);
+ else
+ snprintf (msg, 512, "I haven't heard anything about %s.", entry);
+
+ gdbm_close (dbf);
+ return msg;
+}
+
+char *db_elements (char *file_name)
+{
+ GDBM_FILE dbf;
+ datum key;
+ int count;
+ static char msg[81];
+
+ if ((dbf = gdbm_open (file_name, 512, GDBM_READER, 0, 0)) == NULL)
+ return "db_lookup error";
+
+ key = gdbm_firstkey (dbf);
+
+ count = 0;
+ while (key.dptr != NULL) {
+ key = gdbm_nextkey (dbf, key);
+ count++;
+ }
+
+ gdbm_close (dbf);
+ snprintf (msg, 80, "I am holding %d %s in my database.", count, (count > 0) ? "rows" : "row");
+ return msg;
+}
+
+char *db_list (char *file_name)
+{
+ GDBM_FILE dbf;
+ datum content;
+ datum key;
+ static char msg[81];
+ int count;
+
+ if ((dbf = gdbm_open (file_name, 512, GDBM_READER, 0, 0)) == NULL)
+ return "db_list error";
+
+ key = gdbm_firstkey (dbf);
+
+ count = 0;
+ while (key.dptr) {
+ content = gdbm_fetch (dbf, key);
+ printf ("%11s: %s\n", key.dptr, content.dptr);
+ free (content.dptr);
+ key = gdbm_nextkey (dbf, key);
+ count++;
+ }
+
+ gdbm_close (dbf);
+ snprintf (msg, 80, "I am holding %d %s in my database.", count, (count > 0) ? "rows" : "row");
+ return msg;
+}
+
+char *db_vaccuum (char *file_name)
+{
+ GDBM_FILE dbf;
+ static char msg[81];
+
+ if ((dbf = gdbm_open (file_name, 512, GDBM_WRITER, 0, 0)) == NULL)
+ return "db_vaccuum error";
+
+ gdbm_reorganize (dbf);
+
+ gdbm_close (dbf);
+ snprintf (msg, 80, "I reorganized the database.");
+ return msg;
+}
new file mode 100644
--- /dev/null
+++ b/src/dbtool.c
@@ -0,0 +1,137 @@
+/**
+ * $Id: dbtool.c 51 2008-01-10 00:19:39Z mbroeker $
+ * $URL: http://localhost/svn/c/mcbot/trunk/src/dbtool.c $
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include <database.h>
+
+#ifndef FILE_NAME
+#define FILE_NAME "/var/lib/nobody/data/mcbot.dat"
+#endif
+
+void help (char *prgname)
+{
+ printf ("Usage: %s [[-a|-r] -k <key> -v <value>]\n", prgname);
+ printf (" %s [-d <key>]\n", prgname);
+ printf (" %s [-f <file>]\n", prgname);
+ printf (" %s [-s <key>]\n", prgname);
+ printf (" %s [-h|-?]\n\n", prgname);
+ printf ("Administration tool for adding/replacing, deleting, ... of DataBase Entries.\n\n");
+ printf ("Options:\n");
+ printf (" -a\t\tadds a new key <key> with value <value> to the db\n");
+ printf (" -r\t\treplaces a key <key> with value <value> in the db\n");
+ printf (" -d\t\tdeletes a <key> from the db\n");
+ printf (" -f\t\tsets the db file\n");
+ printf (" -l\t\tlists the db entries\n");
+ printf (" -s\t\tsearches the db entry <key>\n");
+ printf (" -V\t\treorganizes the db\n");
+ printf (" -h\t\tprints this help\n");
+ printf (" -?\t\tprints this help\n\n");
+ printf ("Report bugs to mbroeker@largo.homelinux.org\n");
+ exit (0);
+}
+
+#define ADD 1
+#define REPLACE 2
+#define DELETE 3
+#define SEARCH 4
+#define LIST 5
+#define VACCUUM 6
+
+int main (int argc, char **argv)
+{
+ int i;
+ int mode = 0;
+ char *key = NULL;
+ char *value = NULL;
+ char *file_name = NULL;
+
+ while ((i = getopt (argc, argv, "arlVh?d:f:k:s:v:")) > 0) {
+ switch (i) {
+ case '?':
+ case 'h':
+ help (argv[0]);
+ break;
+ case 'a':
+ mode = ADD;
+ break;
+ case 'r':
+ mode = REPLACE;
+ break;
+ case 'd':
+ mode = DELETE;
+ key = optarg;
+ break;
+ case 'f':
+ file_name = optarg;
+ break;
+ case 'k':
+ key = optarg;
+ break;
+ case 's':
+ key = optarg;
+ mode = SEARCH;
+ break;
+ case 'v':
+ value = optarg;
+ break;
+ case 'l':
+ mode = LIST;
+ break;
+ case 'V':
+ mode = VACCUUM;
+ break;
+ default:
+ printf ("Unknown Option %c\n", i);
+ }
+ }
+
+ for (i = optind; i < argc; i++) {
+ printf ("Unknown Parameter: %s\n", argv[i]);
+ }
+
+ if (!file_name)
+ file_name = FILE_NAME;
+
+ switch (mode) {
+ case ADD:
+ if ((key != NULL) && (value != NULL))
+ printf ("%s\n", db_insert (file_name, key, value, 0));
+ else
+ help (argv[0]);
+ break;
+ case REPLACE:
+ if ((key != NULL) && (value != NULL))
+ printf ("%s\n", db_insert (file_name, key, value, 1));
+ else
+ help (argv[0]);
+ break;
+ case DELETE:
+ if (key != NULL)
+ printf ("%s\n", db_remove (file_name, key));
+ else
+ help (argv[0]);
+ break;
+ case SEARCH:
+ if (key != NULL)
+ printf ("%s\n", db_lookup (file_name, key));
+ else
+ help (argv[0]);
+ break;
+ case LIST:
+ printf ("%s\n", db_list (file_name));
+ break;
+ case VACCUUM:
+ printf ("%s\n", db_vaccuum (file_name));
+ break;
+ default:
+ printf ("Nothing to do: Try %s -h\n", argv[0]);
+ }
+
+ return EXIT_SUCCESS;
+}
new file mode 100644
--- /dev/null
+++ b/src/irc.c
@@ -0,0 +1,323 @@
+/**
+ * $Id: irc.c 51 2008-01-10 00:19:39Z mbroeker $
+ * $URL: http://localhost/svn/c/mcbot/trunk/src/irc.c $
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <pwd.h>
+
+#include <irc.h>
+
+#define VERSION_STRING "MCBOT on GNU/LINUX"
+
+const char *IRC_Commands[] = {
+ "NOTICE", "MODE", "JOIN", "PART",
+ "TOPIC", "PING", "ENOMEM", "ERROR",
+ "VERSION", "PRIVMSG", "QUIT", "NICK",
+ NULL,
+};
+
+FILE *irc_connect (char *server, unsigned int port)
+{
+ struct hostent *he;
+ char *ip;
+ struct sockaddr_in ca;
+ int csocket;
+ FILE *stream;
+
+ he = gethostbyname (server);
+ if (he == NULL) {
+ perror ("GETHOSTBYNAME");
+ return NULL;
+ }
+
+ if ((ip = inet_ntoa (*((struct in_addr *)he->h_addr_list[0]))) == NULL) {
+ perror ("GETHOSTBYNAME");
+ return NULL;
+ } else
+ printf ("IP: %s\n", ip);
+
+ ca.sin_family = AF_INET;
+ ca.sin_addr.s_addr = inet_addr (ip);
+ ca.sin_port = htons (port);
+
+ csocket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (connect (csocket, (struct sockaddr *)&ca, (socklen_t) sizeof (ca)) == -1) {
+ perror ("CONNECT");
+ return NULL;
+ }
+
+ /*
+ * rw mode,but many seek errors ...
+ */
+ stream = fdopen (csocket, "a+");
+ return stream;
+}
+
+int irc_login (FILE * stream, char *nick, char *password)
+{
+ MSG message;
+ char msg[513];
+ char *user;
+ struct passwd *pwd = NULL;
+
+ if ((user = getenv ("USER")) != NULL)
+ if ((pwd = getpwnam (user)) == NULL)
+ return IRC_GENERAL_ERROR;
+
+ if (strlen (password) == 0)
+ return IRC_LOGIN_ERROR;
+
+ if (stream == NULL)
+ return IRC_GENERAL_ERROR;
+
+ fprintf (stream, "NICK %s\r\n", nick);
+
+ fprintf (stream, "USER %s 0 irc.freenode.net %s\r\n", user, pwd->pw_gecos);
+
+ fprintf (stream, "PRIVMSG NICKSERV :IDENTIFY %s\r\n", password);
+
+ for (;;) {
+ fgets (msg, 512, stream);
+ if ((user = irc_parsemessage (msg, &message)) != NULL)
+ printf ("%10s %s\n", user, message.line);
+
+ if (strstr (msg, "VERSION") != NULL) {
+ printf ("%10s %s", "VERSION", msg);
+ printf ("%10s %s %s :%s\n", "WRITE", message.command, message.user, VERSION_STRING);
+ fprintf (stream, "VERSION :%s\r\n", VERSION_STRING);
+ }
+
+ if (strstr (msg, ":Password accepted") != NULL) {
+ break;
+ }
+
+ if (strstr (msg, ":Password Incorrect") != NULL) {
+ return IRC_LOGIN_ERROR;
+ }
+
+ if (strstr (msg, "ERROR :Closing Link") != NULL) {
+ return IRC_GENERAL_ERROR;
+ }
+
+ if (strstr (msg, "is not registered") != NULL) {
+ return IRC_LOGIN_ERROR;
+ }
+ }
+
+ sleep (2);
+ return 0;
+}
+
+static char *irc_getmessage (const char *line, MSG * message)
+{
+ char *theLine;
+ char *token;
+ char *ptr;
+
+ if ((theLine = strdup (line)) == NULL)
+ return "ENOMEM";
+
+ message->user = message->email = NULL;
+ message->command = NULL;
+ message->channel = message->line = NULL;
+
+ token = strtok (theLine, " ");
+ if (*token != ':') {
+ /*
+ * SERVER MESSAGES
+ */
+ if ((ptr = strtok (NULL, "\r\n")) != NULL)
+ ++ptr;
+ message->line = ptr;
+ return token;
+ }
+
+ message->user = ++token;
+ message->command = strtok (NULL, " ");
+
+ message->line = strtok (NULL, "\r\n");
+
+ return message->command;
+}
+
+/*
+ * Main prints ("%10s %s %s\n", MSG->command MSG->channel MSG->line).
+ * This functions makes sure, that there will be someting to print...
+ */
+
+char *irc_parsemessage (const char *line, MSG * message)
+{
+ int i;
+ char *command;
+ char *ptr;
+ int value;
+
+ i = 0;
+ if ((command = irc_getmessage (line, message)) != NULL) {
+ while (IRC_Commands[i] != NULL) {
+ if (strcmp (IRC_Commands[i], command) == 0) {
+ switch (i) {
+
+ case 0: /* NOTICE */
+ if (message->line == NULL) {
+ message->channel = "*";
+ message->line = "*";
+ } else {
+ message->channel = strtok (message->line, " ");
+ if ((message->line = strtok (NULL, "\r\n")) != NULL)
+ ++message->line;
+ }
+ return command;
+ case 1: /* MODE */
+ message->channel = strtok (message->line, " ");
+ message->line = strtok (NULL, "\r\n");
+ return command;
+ case 2: /* JOIN */
+ case 3: /* PART */
+ if ((message->channel = strchr (message->line, ':')))
+ ++message->channel;
+ message->line = message->user;
+ return command;
+ case 4: /* TOPIC */
+ message->channel = strtok (message->line, " ");
+ if ((message->line = strtok (NULL, "\r\n")))
+ ++message->line;
+ return command;
+ case 5: /* PING */
+#ifdef DEBUG
+ printf ("%10s %s localhost\n", "PING", message->line);
+#endif
+ fprintf (message->stream, "PONG :%s\r\n", message->line);
+ message->channel = "localhost";
+#ifdef DEBUG
+ return "PONG";
+#else
+ return NULL;
+#endif
+ case 6: /* ENOMEM */
+ case 7: /* ERROR */
+ exit (-1);
+ break;
+ case 8: /* VERSION */
+ if ((ptr = strchr (message->user, ' ')))
+ *ptr = 0;
+ return command;
+ case 9: /* PRIVMSG */
+ if ((message->email = strchr (message->user, '=')))
+ ++message->email;
+ if ((ptr = strchr (message->user, '!')))
+ *ptr = 0;
+
+ message->channel = strtok (message->line, " ");
+ message->line = strtok (NULL, "\r\n");
+ message->line++;
+ printf ("%10s %s %s :%s\n", "READ", message->command, message->channel, message->line);
+ return NULL;
+ case 10: /* QUIT */
+ message->channel = message->user;
+ return command;
+ case 11: /* NICK */
+ message->channel = message->user;
+ return command;
+ }
+ }
+ i++;
+ }
+
+ if ((value = atoi (command)) != 0) {
+ switch (value) {
+ case 1: /* CONNECTION INFOS */
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 250:
+ case 251:
+ case 252:
+ case 254:
+ case 255:
+ case 265:
+ case 266:
+ /*
+ * prints as is in irc_login
+ */
+ return command;
+ break;
+ case 311:
+ case 312:
+ case 315: /* END OF WHO */
+ case 318:
+ message->channel = strtok (message->line, " ");
+ message->line = strtok (NULL, "\r\n");
+ return command;
+ case 319:
+ message->channel = strtok (message->line, " ");
+ message->line = strtok (NULL, "\r\n");
+ fprintf (message->stream, "PRIVMSG %s :%s\r\n", "#mcbot", message->line);
+ return command;
+ case 320:
+ case 332: /* TOPIC OF CHANNEL */
+ case 333: /* NAMES IN CHANNEL */
+ message->channel = strtok (message->line, " ");
+ message->line = strtok (NULL, "\r\n");
+ return command;
+ case 351: /* SVERSION */
+ message->channel = strtok (message->line, " ");
+ message->line = strtok (NULL, "\r\n");
+ return command;
+ case 352: /* WHO LIST */
+ message->channel = strtok (message->line, " ");
+ message->line = strtok (NULL, "\r\n");
+ /*
+ * MORE THAN 3 LINES AND YOU WILL be KICKED
+ */
+ return command;
+ break;
+ case 353:
+ case 365:
+ case 366: /* END OF NAMES */
+ message->channel = strtok (message->line, " ");
+ message->line = strtok (NULL, "\r\n");
+ return command;
+ break;
+ case 372: /* MOTD MESSAGES */
+ case 375:
+ case 376: /* END OF MOTD */
+ return command;
+ break;
+ case 401: /* NO SUCH NICK/CHANNEL */
+ case 403: /* That CHANNEL doesnt exist */
+ return command;
+ break;
+ case 474:
+ case 475:
+ case 476:
+ case 477:
+ message->channel = strtok (message->line, " ");
+ message->line = strtok (NULL, "\r\n");
+ return command;
+ break;
+ default:
+ printf ("DEBUG %s", line);
+ printf ("Unknown Value: %d\n", value);
+ }
+ }
+ printf ("DEBUG %s", line);
+ printf ("Unknown Command: %s\n", command);
+ return command;
+ }
+ printf ("DEBUG %s", line);
+ return NULL;
+}
new file mode 100644
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,135 @@
+/**
+ * $Id: main.c 51 2008-01-10 00:19:39Z mbroeker $
+ * $URL: http://localhost/svn/c/mcbot/trunk/src/main.c $
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <signal.h>
+#include <locale.h>
+#include <libintl.h>
+
+#include <mcbot.h>
+#include <config.h>
+
+#ifndef CONFIG_FILE
+#define CONFIG_FILE "/var/lib/nobody/.mcbotrc"
+#endif
+
+#ifndef LOCALE_PATH
+#define LOCALE_PATH "/var/lib/nobody/data/locale"
+#endif
+
+short active = 1;
+
+void sigproc ()
+{
+ signal (SIGTERM, sigproc);
+ active = 0;
+}
+
+int main (int argc, char **argv)
+{
+ UC uc;
+ MSG message;
+ char buf[513];
+ char *msg;
+ char *command;
+ int len;
+
+ if (bindtextdomain ("mcbot", LOCALE_PATH) != NULL) {
+ (void)textdomain ("mcbot");
+ (void)setlocale (LC_MESSAGES, "");
+ }
+
+ printf ("mcbot-%1.2f\n", VERSION);
+
+ if ((len = config (&uc, CONFIG_FILE)) != 0) {
+ switch (len) {
+ case -1:
+ printf ("You need to create a config file %s\n", CONFIG_FILE);
+ break;
+ case -2:
+ printf
+ ("You need at least entries for user, password, server and channel in your config file %s\n",
+ CONFIG_FILE);
+ break;
+ }
+ return len;
+ }
+
+ if (uc.nick)
+ message.nick = uc.nick;
+ else
+ return -1;
+
+ if (!(message.stream = irc_connect (uc.server, uc.port)))
+ return EXIT_FAILURE;
+
+ if ((len = irc_login (message.stream, uc.nick, uc.pass)) != 0) {
+ switch (len) {
+ case IRC_GENERAL_ERROR:
+ printf ("GENERAL ERROR\n");
+ break;
+ case IRC_LOGIN_ERROR:
+ printf ("LOGIN ERROR\n");
+ break;
+ default:
+ printf ("Unknown Error %d\n", len);
+ }
+ return len;
+ }
+
+ signal (SIGTERM, sigproc);
+
+ if (uc.channel) {
+ fprintf (message.stream, "JOIN :%s\r\n", uc.channel);
+ if (uc.topic)
+ fprintf (message.stream, "TOPIC %s :%s\r\n", uc.channel, uc.topic);
+ }
+
+ while (active) {
+ if (fgets (buf, 512, message.stream) == NULL) {
+ active = 0;
+ break;
+ }
+
+ if ((command = irc_parsemessage (buf, &message))) {
+ printf ("%10s %s %s\n", command, message.channel, message.line);
+ } else {
+ if ((msg = parse (&message, &active)) != NULL) {
+ fprintf (message.stream, "%s\r\n", msg);
+ printf ("%10s %s", "WRITE", msg);
+ }
+ }
+ *buf = 0;
+ }
+ printf ("\n\nClosing Connection\n\n");
+ fclose (message.stream);
+
+ /*
+ * cleanup
+ */
+
+ if (uc.nick)
+ free (uc.nick);
+ if (uc.pass)
+ free (uc.pass);
+ if (uc.server)
+ free (uc.server);
+ if (uc.channel)
+ free (uc.channel);
+ if (uc.topic)
+ free (uc.topic);
+
+ return EXIT_SUCCESS;
+}
new file mode 100644
--- /dev/null
+++ b/src/parse.c
@@ -0,0 +1,278 @@
+/**
+ * $Id: parse.c 153 2008-04-27 07:26:15Z mbroeker $
+ * $URL: http://localhost/svn/c/mcbot/trunk/src/parse.c $
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <mcbot.h>
+#include <database.h>
+
+#include <locale.h>
+#include <libintl.h>
+
+#ifndef DATABASE_FILE
+#define DATABASE_FILE "/var/lib/nobody/data/mcbot.dat"
+#endif
+
+const
+char *COMMAND_LIST[] = {
+ "!help Known Commands: join(1), leave(2), add(3), replace(4), delete(5), list(6), search(7), info(8)\r\n",
+ "!join: Joins a new channel\r\n",
+ "!leave: Parts from the current channel\r\n",
+ "!add: adds an entry\r\n",
+ "!replace: replaces an entry\r\n",
+ "!delete: deletes an entry\r\n",
+ "!list: lists the number of stored values\r\n",
+ "!search: searches an entry up\r\n",
+ "!info: Prints the current Bot-Version\r\n",
+ "!ping: pings an host\r\n",
+ "!on: enables autolearning mode\r\n",
+ "!off: disables autolearning\r\n",
+ "!debug: prints some debug infos\r\n",
+ "!vaccuum: reorganizes the database\r\n",
+ "!logout: Protected logout function\r\n",
+ NULL,
+};
+
+const
+char ITEMS = 14;
+
+const
+char *Bot_Commands[] = {
+ "!help", "!join", "!leave",
+ "!add", "!replace", "!delete",
+ "!list", "!search", "!info",
+ "!ping", "!on", "!off",
+ "!debug", "!vaccuum", "!logout",
+ "!who", "!whois", "!time", "!tell",
+ "!op",
+ NULL,
+};
+
+char *parse (MSG * message, short *active)
+{
+ static char msg[513];
+ int cmd = -1;
+ int i;
+ char *token;
+ char *parameters;
+
+ time_t t;
+ struct tm *timeptr;
+ static int counter = 0;
+
+ /*
+ * default message
+ */
+ snprintf (msg, 512, "PRIVMSG %s :%s.\r\n", message->channel, gettext ("Request cannot be performed"));
+
+ /*
+ * PRIVATE MESSAGES
+ */
+ if (!strcmp (message->channel, message->nick))
+ message->channel = message->user;
+
+ if (strstr (message->line, message->nick)) {
+ if (*message->line != '!') {
+ /*
+ * DEAD - LOCK - CHECK
+ */
+ if (strcmp (message->user, message->nick)) {
+ snprintf (msg, 512, "PRIVMSG %s :%s, %s?\r\n", message->channel, gettext ("What's up"), message->user);
+ if (counter++ > 3)
+ return NULL;
+ return msg;
+ }
+ /*
+ * DEAD - LOCK - CHECK ENDS
+ */
+ }
+ return NULL;
+ }
+
+ counter = 0;
+
+ /*
+ * NO BOT Commands
+ */
+ if (*message->line != '!') {
+ return NULL;
+ }
+
+ i = 0;
+ token = strtok (message->line, " ");
+ while (Bot_Commands[i]) {
+ if (!strcmp (token, Bot_Commands[i])) {
+ switch (i) {
+ case 0: /* !help */
+ if ((token = strtok (NULL, "\r\n")))
+ cmd = atoi (token);
+ if ((cmd > 0) && (cmd < ITEMS))
+ snprintf (msg, 512, "PRIVMSG %s :%s\r\n", message->channel, COMMAND_LIST[cmd]);
+ else
+ snprintf (msg, 512, "PRIVMSG %s :%s\r\n", message->channel, COMMAND_LIST[0]);
+ return msg;
+
+ case 1: /* !join */
+ if ((token = strtok (NULL, "\r\n")))
+ snprintf (msg, 512, "JOIN %s\r\n", token);
+ return msg;
+
+ case 2: /* !leave */
+ if (*message->channel != '#')
+ return NULL;
+ snprintf (msg, 512, "PART %s :Leaving.\r\n", message->channel);
+ return msg;
+
+ case 3: /* !add */
+ if ((token = strtok (NULL, " "))) {
+ if ((parameters = strtok (NULL, "\r\n"))) {
+ snprintf (msg, 512, "PRIVMSG %s :%s, %s\r\n",
+ message->channel, message->user, db_insert (DATABASE_FILE, token, parameters, 0));
+ } else {
+ snprintf (msg, 512,
+ "PRIVMSG %s :%s, %s!\r\n",
+ message->channel, gettext ("I need more parameters to add"), message->user);
+ }
+ }
+ return msg;
+
+ case 4: /* !replace */
+ if ((token = strtok (NULL, " "))) {
+ if ((parameters = strtok (NULL, "\r\n"))) {
+ snprintf (msg, 512, "PRIVMSG %s :%s, %s\r\n",
+ message->channel, message->user, db_insert (DATABASE_FILE, token, parameters, 1));
+ } else {
+ snprintf (msg, 512,
+ "PRIVMSG %s :%s, %s!\r\n",
+ message->channel, gettext ("I need more parameters to replace"), message->user);
+ }
+ }
+ return msg;
+
+ case 5: /* !delete */
+ if ((token = strtok (NULL, "\r\n"))) {
+ snprintf (msg, 512, "PRIVMSG %s :%s, %s\r\n",
+ message->channel, message->user, db_remove (DATABASE_FILE, token));
+ } else {
+ snprintf (msg, 512,
+ "PRIVMSG %s :%s, %s!\r\n",
+ message->channel, gettext ("I need a key to delete"), message->user);
+ }
+ return msg;
+
+ case 6: /* !count */
+ snprintf (msg, 512, "PRIVMSG %s :%s %s\r\n", message->channel,
+ db_elements (DATABASE_FILE), db_lookup(DATABASE_FILE, "mcbot.cgi"));
+ return msg;
+
+ case 7: /* !search */
+ if ((token = strtok (NULL, "\r\n"))) {
+ snprintf (msg, 512, "PRIVMSG %s :%s, %s\r\n",
+ message->channel, message->user, db_lookup (DATABASE_FILE, token));
+ } else {
+ snprintf (msg, 512,
+ "PRIVMSG %s :%s, %s!\r\n",
+ message->channel, gettext ("I need a key to lookup"), message->user);
+ }
+ return msg;
+
+ case 8: /* !info */
+ snprintf (msg, 512,
+ "PRIVMSG %s :I am MCBot-%1.2f and my source code can be found on %s\r\n",
+ message->channel, VERSION, "http://largo.homelinux.org/svn/c/mcbot/trunk");
+ return msg;
+
+ case 9: /* !ping */
+ if ((token = strtok (NULL, "\r\n")))
+ snprintf (msg, 512, "PRIVMSG %s :PING 0815\r\n", token);
+ return msg;
+
+ case 10: /* !on */
+ snprintf (msg, 512,
+ "PRIVMSG %s :%s %s.\r\n",
+ message->user, gettext ("Autolearn enabled for channel"), message->channel);
+ return msg;
+
+ case 11: /* !off */
+ snprintf (msg, 512,
+ "PRIVMSG %s :%s %s.\r\n",
+ message->user, gettext ("Autolearn disabled for channel"), message->channel);
+ return msg;
+
+ case 12: /* !debug */
+ snprintf (msg, 512,
+ "PRIVMSG %s :USER: %s EMAIL: %s CHANNEL: %s LINE: %s\r\n",
+ message->channel, message->user, message->email, message->channel, message->line);
+ return msg;
+
+ case 13: /* !vaccum */
+ snprintf (msg, 512, "PRIVMSG %s :%s\r\n", message->channel, db_vaccuum (DATABASE_FILE));
+ return msg;
+
+ case 14: /* !logout */
+ if (strstr (message->user, db_lookup(DATABASE_FILE, "mcbot.user"))) {
+ if (strstr (message->email, db_lookup(DATABASE_FILE, "mcbot.email"))) {
+ snprintf (msg, 512,
+ "PRIVMSG %s :%s!\r\nQUIT\r\n", message->channel, gettext ("Bye, have a nice day!"));
+ *active = 0;
+ }
+ }
+ /*
+ * the returned message is either the default one or the generated one
+ */
+ return msg;
+
+ case 15: /* !who */
+ if ((token = strtok (NULL, "\r\n")) != NULL) {
+ snprintf (msg, 512, "WHO %s\r\n", token);
+ }
+ return msg;
+ break;
+
+ case 16: /* !whois */
+ if ((token = strtok (NULL, "\r\n")) != NULL) {
+ snprintf (msg, 512, "WHOIS %s\r\n", token);
+ }
+ return msg;
+ break;
+ case 17: /* time */
+ t = time (NULL);
+ timeptr = localtime (&t);
+ if ((token = malloc (81))) {
+ strftime (token, 80, "%I:%M:%S %p", timeptr);
+ snprintf (msg, 512, "PRIVMSG %s :%s %s, %s!\r\n",
+ message->channel, gettext ("It is"), token, message->user);
+ free (token);
+ }
+ return msg;
+ break;
+ case 18: /* tell */
+ if ((token = strtok (NULL, " "))) {
+ if ((parameters = strtok (NULL, "\r\n"))) {
+ snprintf (msg, 512, "PRIVMSG %s :%s, %s\r\n",
+ (*token ==
+ '*') ? ++token : message->channel, token, db_lookup (DATABASE_FILE, parameters));
+ }
+ }
+ return msg;
+ break;
+ case 19: /* op */
+ if ((token = strtok (NULL, "\r\n")) != NULL) {
+ if (strstr (message->email, db_lookup(DATABASE_FILE, "mcbot.email")))
+ snprintf (msg, 512, "MODE %s +o %s\r\n", message->channel, token);
+ }
+ return msg;
+ break;
+ }
+ }
+ i++;
+ }
+
+ return NULL;
+}