safe buffers, a memory leak and cleanups
sizeof(buffer) is always the right choice for a static buffer...
The error handler must appear before the printf
Useful make targets like deb and debclean
Trivial changes like removing trailing white spaces
committer: Markus Bröker <mbroeker@largo.homelinux.org>
/**
* $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 "common.h"
#include <locale.h>
#include <libintl.h>
#ifndef DATABASE_FILE
#define DATABASE_FILE "/var/lib/mcbot/data/mcbot.dat"
#endif
#ifndef SOURCE_URL
#define SOURCE_URL "http://largo.homelinux.org/cgi-bin/gitweb.cgi?p=net/mcbot.git"
#endif
enum {
HELP, JOIN, LEAVE, ADD, REPLACE, DELETE, LIST, SEARCH, INFO, PING, ON, OFF, DEBUG,
VACCUUM, LOGOUT, WHO, WHOIS, TIME, TELL, OP, DEOP, KICK, BAN, UNBAN, KICKBAN, HELLO
};
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 VISIBLE_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", "!deop",
"!kick", "!ban", "!unban",
"!kickban", "!hello",
NULL
};
char *parse (MSG * message)
{
static char msg[DEFAULT_BUF_SIZE];
int cmd = -1;
int i;
char *token;
char *parameters;
time_t t;
struct tm *timeptr;
/*
* default message
*/
snprintf (msg, sizeof (msg), "PRIVMSG %s :%s.\r\n", message->channel, gettext ("Request cannot be performed"));
/*
* PRIVATE MESSAGES
*/
if (!strcmp (message->channel, message->nick))
message->channel = message->user;
/*
* 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 HELP:
if ((token = strtok (NULL, "\r\n")))
cmd = atoi (token);
if ((cmd > 0) && (cmd < VISIBLE_ITEMS))
snprintf (msg, sizeof (msg), "PRIVMSG %s :%s\r\n", message->channel, COMMAND_LIST[cmd]);
else
snprintf (msg, sizeof (msg), "PRIVMSG %s :%s\r\n", message->channel, COMMAND_LIST[0]);
return msg;
case JOIN:
if ((token = strtok (NULL, "\r\n")))
if (strstr (message->user, db_lookup (DATABASE_FILE, "mcbot.user"))) {
if (strstr (message->email, db_lookup (DATABASE_FILE, "mcbot.email")))
snprintf (msg, sizeof (msg), "JOIN %s\r\n", token);
}
return msg;
case LEAVE:
if (*message->channel != '#')
return NULL;
if (strstr (message->user, db_lookup (DATABASE_FILE, "mcbot.user"))) {
if (strstr (message->email, db_lookup (DATABASE_FILE, "mcbot.email")))
snprintf (msg, sizeof (msg), "PART %s :Leaving.\r\n", message->channel);
}
return msg;
case ADD:
if ((token = strtok (NULL, " "))) {
if ((parameters = strtok (NULL, "\r\n"))) {
snprintf (msg, sizeof (msg), "PRIVMSG %s :%s, %s\r\n",
message->channel, message->user, db_insert (DATABASE_FILE, token, parameters, 0));
} else {
snprintf (msg, sizeof (msg), "PRIVMSG %s :%s, %s!\r\n", message->channel,
gettext ("I need more parameters to add"), message->user);
}
}
return msg;
case REPLACE:
if ((token = strtok (NULL, " "))) {
if ((parameters = strtok (NULL, "\r\n"))) {
snprintf (msg, sizeof (msg), "PRIVMSG %s :%s, %s\r\n",
message->channel, message->user, db_insert (DATABASE_FILE, token, parameters, 1));
} else {
snprintf (msg, sizeof (msg), "PRIVMSG %s :%s, %s!\r\n", message->channel,
gettext ("I need more parameters to replace"), message->user);
}
}
return msg;
case DELETE:
if ((token = strtok (NULL, "\r\n"))) {
snprintf (msg, sizeof (msg), "PRIVMSG %s :%s, %s\r\n",
message->channel, message->user, db_remove (DATABASE_FILE, token));
} else {
snprintf (msg, sizeof (msg), "PRIVMSG %s :%s, %s!\r\n", message->channel,
gettext ("I need a key to delete"), message->user);
}
return msg;
case LIST:
snprintf (msg, sizeof (msg), "PRIVMSG %s :%s %s\r\n", message->channel, db_elements (DATABASE_FILE),
db_lookup (DATABASE_FILE, "mcbot.cgi"));
return msg;
case SEARCH:
if ((token = strtok (NULL, "\r\n"))) {
snprintf (msg, sizeof (msg), "PRIVMSG %s :%s, %s\r\n", message->channel, message->user,
db_lookup (DATABASE_FILE, token));
} else {
snprintf (msg, sizeof (msg),
"PRIVMSG %s :%s, %s!\r\n", message->channel, gettext ("I need a key to lookup"),
message->user);
}
return msg;
case INFO:
snprintf (msg, sizeof (msg),
"PRIVMSG %s :I am MCBot-%1.2f Build %s and my source code can be found at %s\r\n",
message->channel, BOT_VERSION, BOT_BUILD, SOURCE_URL);
return msg;
case PING:
if ((token = strtok (NULL, "\r\n")))
snprintf (msg, sizeof (msg), "PRIVMSG %s :PING 0815\r\n", token);
return msg;
case ON:
snprintf (msg, sizeof (msg), "PRIVMSG %s :%s %s.\r\n", message->user,
gettext ("Autolearn enabled for channel"), message->channel);
return msg;
case OFF:
snprintf (msg, sizeof (msg), "PRIVMSG %s :%s %s.\r\n", message->user,
gettext ("Autolearn disabled for channel"), message->channel);
return msg;
case DEBUG:
snprintf (msg, sizeof (msg), "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 VACCUUM:
snprintf (msg, sizeof (msg), "PRIVMSG %s :%s\r\n", message->channel, db_vaccuum (DATABASE_FILE));
return msg;
case LOGOUT:
if (strstr (message->user, db_lookup (DATABASE_FILE, "mcbot.user"))) {
if (strstr (message->email, db_lookup (DATABASE_FILE, "mcbot.email"))) {
snprintf (msg, sizeof (msg), "PRIVMSG %s :%s!\r\nQUIT\r\n", message->channel,
gettext ("Bye, have a nice day!"));
}
}
/*
* the returned message is either the default one or the generated one
*/
return msg;
case WHO:
if ((token = strtok (NULL, "\r\n")) != NULL) {
snprintf (msg, sizeof (msg), "WHO %s\r\n", token);
}
return msg;
case WHOIS:
if ((token = strtok (NULL, "\r\n")) != NULL) {
snprintf (msg, sizeof (msg), "WHOIS %s\r\n", token);
}
return msg;
case TIME:
t = time (NULL);
timeptr = localtime (&t);
if ((token = malloc (81))) {
strftime (token, 80, "%I:%M:%S %p", timeptr);
snprintf (msg, sizeof (msg), "PRIVMSG %s :%s %s, %s!\r\n", message->channel, gettext ("It is"),
token, message->user);
free (token);
}
return msg;
case TELL:
if ((token = strtok (NULL, " "))) {
if ((parameters = strtok (NULL, "\r\n"))) {
if (*token == '*')
message->channel = ++token;
snprintf (msg, sizeof (msg), "PRIVMSG %s :%s, %s\r\n", message->channel, token,
db_lookup (DATABASE_FILE, parameters));
}
}
return msg;
case OP:
if ((token = strtok (NULL, "\r\n")) != NULL) {
if (strstr (message->user, db_lookup (DATABASE_FILE, "mcbot.user"))) {
if (strstr (message->email, db_lookup (DATABASE_FILE, "mcbot.email")))
snprintf (msg, sizeof (msg), "MODE %s +o %s\r\n", message->channel, token);
}
}
return msg;
case DEOP:
if ((token = strtok (NULL, "\r\n")) != NULL) {
if (strstr (message->user, db_lookup (DATABASE_FILE, "mcbot.user"))) {
if (strstr (message->email, db_lookup (DATABASE_FILE, "mcbot.email")))
snprintf (msg, sizeof (msg), "MODE %s -o %s\r\n", message->channel, token);
}
}
return msg;
case KICK:
if ((token = strtok (NULL, "\r\n")) != NULL) {
if (strstr (message->user, db_lookup (DATABASE_FILE, "mcbot.user"))) {
if (strstr (message->email, db_lookup (DATABASE_FILE, "mcbot.email")))
snprintf (msg, sizeof (msg), "KICK %s %s\r\n", message->channel, token);
}
}
return msg;
case BAN:
if ((token = strtok (NULL, "\r\n")) != NULL) {
if (strstr (message->user, db_lookup (DATABASE_FILE, "mcbot.user"))) {
if (strstr (message->email, db_lookup (DATABASE_FILE, "mcbot.email")))
snprintf (msg, sizeof (msg), "MODE %s +b %s\r\n", message->channel, token);
}
}
return msg;
case UNBAN:
if ((token = strtok (NULL, "\r\n")) != NULL) {
if (strstr (message->user, db_lookup (DATABASE_FILE, "mcbot.user"))) {
if (strstr (message->email, db_lookup (DATABASE_FILE, "mcbot.email")))
snprintf (msg, sizeof (msg), "MODE %s -b %s\r\n", message->channel, token);
}
}
return msg;
case KICKBAN:
if ((token = strtok (NULL, "\r\n")) != NULL) {
if (strstr (message->user, db_lookup (DATABASE_FILE, "mcbot.user"))) {
if (strstr (message->email, db_lookup (DATABASE_FILE, "mcbot.email")))
snprintf (msg, sizeof (msg), "MODE %s +b %s\r\nKICK %s %s\r\n", message->channel, token,
message->channel, token);
}
}
return msg;
case HELLO:
snprintf (msg, sizeof (msg), "PRIVMSG %s :%s, %s?\r\n", message->channel, gettext ("What's up"),
message->user);
return msg;
}
}
i++;
}
return NULL;
}