safe_strncpy replaces the insecure strncpy function
strncpy copies up to n bytes and does not terminate it, except the
null byte is in the first n bytes...
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 command_map {
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,
TOPIC,
};
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",
"topic Sets a new topic\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", "!topic",
NULL
};
char *parse (MSG * message)
{
static char msg[DEFAULT_BUF_SIZE];
int cmd = -1;
enum command_map map;
char *token;
char *parameters;
time_t t;
struct tm *timeptr;
/*
* make sure that parseable data is available
* this prevents a possible segmentation fault
*/
if (message->user == NULL)
message->user = "error";
if (message->domain == NULL)
message->domain = "server.err";
/*
* 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;
}
map = 0;
token = strtok (message->line, " ");
while (Bot_Commands[map]) {
if (!strcmp (token, Bot_Commands[map])) {
switch (map) {
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->domain, db_lookup (DATABASE_FILE, "mcbot.domain")))
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->domain, db_lookup (DATABASE_FILE, "mcbot.domain")))
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 domain: %s CHANNEL: %s LINE: %s\r\n",
message->channel, message->user, message->domain, 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->domain, db_lookup (DATABASE_FILE, "mcbot.domain"))) {
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->domain, db_lookup (DATABASE_FILE, "mcbot.domain")))
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->domain, db_lookup (DATABASE_FILE, "mcbot.domain")))
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->domain, db_lookup (DATABASE_FILE, "mcbot.domain")))
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->domain, db_lookup (DATABASE_FILE, "mcbot.domain")))
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->domain, db_lookup (DATABASE_FILE, "mcbot.domain")))
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->domain, db_lookup (DATABASE_FILE, "mcbot.domain")))
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;
case TOPIC:
if ((token = strtok (NULL, "\r\n")) == NULL)
return NULL;
snprintf (msg, sizeof (msg), "TOPIC %s :%s\r\n", message->channel, token);
return msg;
}
}
map++;
}
return NULL;
}