This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
deb-mbse/mbtask/taskchat.c

860 lines
23 KiB
C
Raw Normal View History

/*****************************************************************************
*
* $Id$
* Purpose ...............: mbtask - chat server
*
*****************************************************************************
2006-01-24 22:36:58 +00:00
* Copyright (C) 1997-2006
*
* Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10
* 1971 BV IJmuiden
* the Netherlands
*
* This file is part of MBSE BBS.
*
* This BBS is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* MBSE BBS 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MBSE BBS; see the file COPYING. If not, write to the Free
* Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*****************************************************************************/
#include "../config.h"
2004-02-21 17:22:00 +00:00
#include "../lib/mbselib.h"
2003-03-24 19:44:38 +00:00
#include "taskutil.h"
#include "taskregs.h"
#include "taskchat.h"
2005-04-16 14:49:58 +00:00
#include "taskibc.h"
2005-04-15 21:36:44 +00:00
2003-03-24 19:44:38 +00:00
#define MAXMESSAGES 100 /* Maximum ringbuffer for messages */
/*
* Buffer for messages, this is the structure of a ringbuffer which will
* hold all messages, private public etc. There is one global input pointer
* which points to the current head of the ringbuffer. When a user connects
* to a channel, he will get the latest messages in the channel if they
* are present.
*/
typedef struct _chatmsg {
pid_t topid; /* Destination pid of message */
char fromname[36]; /* Message from user */
char message[81]; /* The message to display */
time_t posted; /* Timestamp for posted message */
} _chat_messages;
/*
* The buffers
*/
2003-04-01 21:41:36 +00:00
_chat_messages chat_messages[MAXMESSAGES];
2003-03-24 19:44:38 +00:00
int buffer_head = 0; /* Messages buffer head */
extern struct sysconfig CFG; /* System configuration */
2003-04-03 20:51:19 +00:00
extern int s_bbsopen; /* The BBS open status */
2005-04-20 16:59:32 +00:00
extern srv_list *servers; /* Connected servers */
2005-04-20 20:27:32 +00:00
extern usr_list *users; /* Connected users */
2005-04-23 14:27:52 +00:00
extern chn_list *channels; /* Connected channels */
2005-04-22 20:10:03 +00:00
extern int usrchg;
2005-04-23 14:27:52 +00:00
extern int chnchg;
2005-05-01 13:35:43 +00:00
extern int srvchg;
2006-02-15 19:56:26 +00:00
extern int Run_IBC;
2003-03-24 19:44:38 +00:00
2003-04-01 21:41:36 +00:00
/*
* Prototypes
*/
2006-02-13 19:26:30 +00:00
void Chatlog(char *, char *, char *);
2003-04-03 20:51:19 +00:00
void chat_dump(void);
void system_msg(pid_t, char *);
2006-02-04 16:30:48 +00:00
void chat_help(pid_t, int);
2003-04-03 20:51:19 +00:00
int join(pid_t, char *, int);
int part(pid_t, char*);
2003-04-01 21:41:36 +00:00
2006-01-23 18:59:16 +00:00
void Chatlog(char *level, char *channel, char *msg)
{
char *logm;
if (CFG.iAutoLog && strlen(CFG.chat_log)) {
logm = calloc(PATH_MAX, sizeof(char));
snprintf(logm, PATH_MAX, "%s/log/%s", getenv("MBSE_ROOT"), CFG.chat_log);
ulog(logm, level, channel, (char *)"-1", msg);
free(logm);
}
}
2003-04-01 21:41:36 +00:00
void chat_dump(void)
{
2005-05-01 12:27:27 +00:00
int first;
usr_list *tmpu;
2003-04-01 21:41:36 +00:00
2003-04-02 21:36:47 +00:00
first = TRUE;
2005-05-01 12:27:27 +00:00
for (tmpu = users; tmpu; tmpu = tmpu->next) {
if (tmpu->pid) {
if (first) {
Syslog('c', " pid username nick channel sysop");
Syslog('c', "----- ------------------------------------ --------- -------------------- -----");
2005-05-01 12:27:27 +00:00
first = FALSE;
}
Syslog('c', "%5d %-36s %-9s %-20s %s", tmpu->pid, tmpu->realname, tmpu->nick,
2005-05-01 13:12:41 +00:00
tmpu->channel, tmpu->sysop?"True ":"False");
2005-05-01 12:27:27 +00:00
}
}
2003-04-01 21:41:36 +00:00
}
2003-03-24 19:44:38 +00:00
/*
* Put a system message into the chatbuffer
*/
void system_msg(pid_t pid, char *msg)
{
if (buffer_head < MAXMESSAGES)
buffer_head++;
else
buffer_head = 0;
memset(&chat_messages[buffer_head], 0, sizeof(_chat_messages));
chat_messages[buffer_head].topid = pid;
2006-03-06 16:34:26 +00:00
strncpy(chat_messages[buffer_head].fromname, "Server", 36);
2003-03-24 19:44:38 +00:00
strncpy(chat_messages[buffer_head].message, msg, 80);
chat_messages[buffer_head].posted = time(NULL);
}
2005-04-22 21:18:45 +00:00
/*
* Shout a message to all users
*/
void system_shout(const char *format, ...)
{
2005-09-11 13:07:42 +00:00
char *buf;
2005-04-22 21:18:45 +00:00
va_list va_ptr;
2005-05-01 12:27:27 +00:00
usr_list *tmpu;
2005-04-22 21:18:45 +00:00
2005-09-11 13:07:42 +00:00
buf = calloc(512, sizeof(char));
2005-04-22 21:18:45 +00:00
va_start(va_ptr, format);
2005-08-29 21:03:28 +00:00
vsnprintf(buf, 512, format, va_ptr);
2005-04-22 21:18:45 +00:00
va_end(va_ptr);
2005-05-01 12:27:27 +00:00
for (tmpu = users; tmpu; tmpu = tmpu->next)
if (tmpu->pid) {
system_msg(tmpu->pid, buf);
}
2005-09-11 13:07:42 +00:00
2006-01-23 18:59:16 +00:00
Chatlog((char *)"-", (char *)" ", buf);
2005-09-11 13:07:42 +00:00
free(buf);
2005-04-22 21:18:45 +00:00
}
2003-03-24 19:44:38 +00:00
/*
* Show help
*/
2006-02-04 16:30:48 +00:00
void chat_help(pid_t pid, int owner)
2003-03-24 19:44:38 +00:00
{
2003-04-03 20:51:19 +00:00
system_msg(pid, (char *)" Help topics available:");
system_msg(pid, (char *)"");
system_msg(pid, (char *)" /BYE - Exit from chatserver");
system_msg(pid, (char *)" /ECHO <message> - Echo message to yourself");
2003-04-03 20:51:19 +00:00
system_msg(pid, (char *)" /EXIT - Exit from chatserver");
system_msg(pid, (char *)" /JOIN #channel - Join or create a channel");
system_msg(pid, (char *)" /J #channel - Join or create a channel");
// system_msg(pid, (char *)" /KICK <nick> - Kick nick out of the channel");
system_msg(pid, (char *)" /LIST - List active channels");
system_msg(pid, (char *)" /NAMES - List nicks in current channel");
2003-04-03 20:51:19 +00:00
system_msg(pid, (char *)" /NICK <name> - Set new nickname");
system_msg(pid, (char *)" /PART - Leave current channel");
system_msg(pid, (char *)" /QUIT - Exit from chatserver");
2006-02-04 16:52:53 +00:00
if (owner)
system_msg(pid, (char *)" /TOPIC <topic> - Set topic for current channel");
2003-03-24 19:44:38 +00:00
system_msg(pid, (char *)"");
2003-04-03 20:51:19 +00:00
system_msg(pid, (char *)" All other input (without a starting /) is sent to the channel.");
2003-03-24 19:44:38 +00:00
}
2003-04-01 21:41:36 +00:00
/*
* Join a channel
*/
2003-04-03 20:51:19 +00:00
int join(pid_t pid, char *channel, int sysop)
2003-04-01 21:41:36 +00:00
{
2005-04-23 14:27:52 +00:00
char buf[81];
chn_list *tmp;
2005-04-30 12:14:42 +00:00
usr_list *tmpu;
2003-04-01 21:41:36 +00:00
Syslog('c', "Join pid %d to channel %s", pid, channel);
2005-04-23 14:27:52 +00:00
if (channels) {
for (tmp = channels; tmp; tmp = tmp->next) {
if (strcmp(tmp->name, channel) == 0) {
2005-05-01 12:27:27 +00:00
for (tmpu = users; tmpu; tmpu = tmpu->next) {
if (tmpu->pid == pid) {
2006-02-13 19:26:30 +00:00
strncpy(tmpu->channel, channel, 20);
tmp->users++;
2005-05-01 12:27:27 +00:00
Syslog('+', "IBC: user %s has joined channel %s", tmpu->nick, channel);
usrchg = TRUE;
2005-05-01 13:35:43 +00:00
srvchg = TRUE;
chnchg = TRUE;
2005-05-01 12:27:27 +00:00
2005-04-23 14:27:52 +00:00
chat_dump();
2005-08-29 21:03:28 +00:00
snprintf(buf, 81, "%s has joined channel %s, now %d users", tmpu->nick, channel, tmp->users);
2005-04-23 14:27:52 +00:00
chat_msg(channel, NULL, buf);
/*
* The sysop channel is private to the system, no broadcast
*/
2005-04-27 18:53:30 +00:00
if (strcasecmp(channel, "#sysop"))
send_at((char *)"JOIN", tmpu->nick, channel);
2005-04-23 14:27:52 +00:00
return TRUE;
}
}
}
}
}
2003-04-01 21:41:36 +00:00
2003-04-03 20:51:19 +00:00
/*
* A new channel must be created, but only the sysop may create the "sysop" channel
*/
2005-04-27 20:26:53 +00:00
if (!sysop && (strcasecmp(channel, "#sysop") == 0)) {
2005-08-29 21:03:28 +00:00
snprintf(buf, 81, "*** Only the sysop may create channel \"%s\"", channel);
2003-04-03 20:51:19 +00:00
system_msg(pid, buf);
return FALSE;
}
2003-04-01 21:41:36 +00:00
/*
* No matching channel found, add a new channel.
*/
2005-05-01 12:27:27 +00:00
for (tmpu = users; tmpu; tmpu = tmpu->next) {
if (tmpu->pid == pid) {
if (add_channel(&channels, channel, tmpu->nick, CFG.myfqdn) == 0) {
2006-02-13 19:26:30 +00:00
strncpy(tmpu->channel, channel, 20);
2005-05-01 12:27:27 +00:00
Syslog('+', "IBC: user %s created and joined channel %s", tmpu->nick, channel);
usrchg = TRUE;
2005-05-01 13:35:43 +00:00
chnchg = TRUE;
srvchg = TRUE;
2005-05-01 12:27:27 +00:00
2005-08-29 21:03:28 +00:00
snprintf(buf, 81, "* Created channel %s", channel);
2005-04-23 14:27:52 +00:00
chat_msg(channel, NULL, buf);
chat_dump();
if (strcasecmp(channel, "#sysop"))
send_at((char *)"JOIN", tmpu->nick, channel);
2005-04-30 12:14:42 +00:00
2005-04-23 14:27:52 +00:00
return TRUE;
}
}
}
2003-04-01 21:41:36 +00:00
/*
* No matching or free channels
*/
2005-08-29 21:03:28 +00:00
snprintf(buf, 81, "*** Cannot create chat channel %s, no free channels", channel);
2003-04-03 20:51:19 +00:00
system_msg(pid, buf);
2003-04-01 21:41:36 +00:00
return FALSE;
}
/*
* Part from a channel
*/
int part(pid_t pid, char *reason)
{
2006-03-06 16:34:26 +00:00
char buf[81], *p;
2005-04-23 14:27:52 +00:00
chn_list *tmp;
2005-04-30 12:14:42 +00:00
usr_list *tmpu;
2003-04-01 21:41:36 +00:00
2005-04-24 12:14:39 +00:00
if (strlen(reason) > 54)
reason[54] = '\0';
Syslog('c', "Part pid %d from channel, reason %s", pid, reason);
2003-04-01 21:41:36 +00:00
2005-05-01 12:27:27 +00:00
for (tmpu = users; tmpu; tmpu = tmpu->next) {
2005-05-01 13:12:41 +00:00
if ((tmpu->pid == pid) && strlen(tmpu->channel)) {
2005-04-23 14:27:52 +00:00
for (tmp = channels; tmp; tmp = tmp->next) {
2005-05-01 12:27:27 +00:00
if (strcmp(tmp->name, tmpu->channel) == 0) {
2005-04-23 14:27:52 +00:00
/*
* Inform other users
*/
2005-05-01 12:27:27 +00:00
if (reason != NULL) {
chat_msg(tmpu->channel, tmpu->nick, reason);
}
2006-02-04 16:30:48 +00:00
snprintf(buf, 81, "%s has left channel %s, %d users left", tmpu->nick, tmp->name, tmp->users -1);
2005-05-01 12:27:27 +00:00
chat_msg(tmpu->channel, NULL, buf);
if (strcasecmp(tmp->name, (char *)"#sysop")) {
2006-03-06 16:34:26 +00:00
p = xstrcpy(tmp->name);
if (reason && strlen(reason)) {
2006-03-06 16:34:26 +00:00
p = xstrcat(p, (char *)" ");
p = xstrcat(p, reason);
}
2006-03-06 16:34:26 +00:00
send_at((char *)"PART", tmpu->nick, p);
free(p);
2005-04-24 12:14:39 +00:00
}
2005-04-23 14:27:52 +00:00
/*
* Clean channel
*/
2006-02-13 19:26:30 +00:00
if (tmp->users > 0)
tmp->users--;
2006-02-04 16:30:48 +00:00
Syslog('+', "IBC: nick %s leaves channel %s, %d user left", tmpu->nick, tmp->name, tmp->users);
2005-04-23 14:27:52 +00:00
if (tmp->users == 0) {
/*
* Last user in channel, remove channel
*/
2006-02-04 16:30:48 +00:00
snprintf(buf, 81, "* Removed channel %s", tmp->name);
system_msg(pid, buf);
2005-05-01 12:27:27 +00:00
Syslog('+', "IBC: removed channel %s, no more users left", tmp->name);
2005-04-23 14:27:52 +00:00
del_channel(&channels, tmp->name);
}
2005-04-30 12:14:42 +00:00
2005-05-01 12:27:27 +00:00
/*
* Update user data
*/
2006-02-13 19:26:30 +00:00
tmpu->channel[0] = '\0';
2005-05-01 12:27:27 +00:00
usrchg = TRUE;
2005-05-01 13:35:43 +00:00
chnchg = TRUE;
srvchg = TRUE;
2005-04-30 12:14:42 +00:00
2005-04-23 14:27:52 +00:00
chat_dump();
return TRUE;
}
}
}
}
2003-04-01 21:41:36 +00:00
return FALSE;
}
2003-03-24 19:44:38 +00:00
void chat_init(void)
{
2005-04-23 14:27:52 +00:00
memset(&chat_messages, 0, sizeof(chat_messages));
2003-04-01 21:41:36 +00:00
}
void chat_cleanuser(pid_t pid)
{
part(pid, (char *)"I'm hanging up!");
}
/*
* Send message into channel
*/
2005-04-23 14:27:52 +00:00
void chat_msg(char *channel, char *nick, char *msg)
2005-05-01 12:27:27 +00:00
{
2006-03-06 16:34:26 +00:00
char *p;
2005-05-01 12:27:27 +00:00
usr_list *tmpu;
if (nick == NULL)
2006-03-06 16:34:26 +00:00
p = xstrcpy(msg);
else {
p = xstrcpy((char *)"<");
p = xstrcat(p, nick);
p = xstrcat(p, (char *)"> ");
p = xstrcat(p, msg);
}
Chatlog((char *)"+", channel, p);
2005-05-01 12:27:27 +00:00
for (tmpu = users; tmpu; tmpu = tmpu->next) {
2005-05-01 13:12:41 +00:00
if (strlen(tmpu->channel) && (strcmp(tmpu->channel, channel) == 0)) {
2006-03-06 16:34:26 +00:00
system_msg(tmpu->pid, p);
2005-05-01 12:27:27 +00:00
}
}
2006-03-06 16:34:26 +00:00
free(p);
2005-05-01 12:27:27 +00:00
}
2003-03-24 19:44:38 +00:00
/*
* Connect a session to the chatserver.
*/
void chat_connect_r(char *data, char *buf)
2003-03-24 19:44:38 +00:00
{
char *pid, *realname, *nick, *temp;
2006-01-25 18:53:21 +00:00
int count = 0, sys = FALSE;
2005-04-20 16:59:32 +00:00
srv_list *sl;
2005-05-01 12:27:27 +00:00
usr_list *tmpu;
2003-03-24 19:44:38 +00:00
Syslog('c', "CCON:%s", data);
2003-03-24 19:44:38 +00:00
2006-02-15 19:56:26 +00:00
if (! Run_IBC) {
snprintf(buf, 200, "100:1,*** Chatserver not configured;");
return;
}
2003-04-02 21:36:47 +00:00
if (IsSema((char *)"upsalarm")) {
2005-08-29 21:03:28 +00:00
snprintf(buf, 200, "100:1,*** Power failure, running on UPS;");
return;
2003-04-03 20:51:19 +00:00
}
if (s_bbsopen == FALSE) {
2005-08-29 21:03:28 +00:00
snprintf(buf, 200, "100:1,*** The BBS is closed now;");
return;
2003-04-02 21:36:47 +00:00
}
2005-05-01 12:27:27 +00:00
/*
* Register with IBC
*/
pid = strtok(data, ","); /* Should be 3 */
pid = strtok(NULL, ","); /* The pid */
realname = xstrcpy(cldecode(strtok(NULL, ",")));/* Username */
nick = xstrcpy(cldecode(strtok(NULL, ","))); /* Nickname */
sys = atoi(strtok(NULL, ";")); /* Sysop flag */
2005-05-01 12:27:27 +00:00
add_user(&users, CFG.myfqdn, nick, realname);
send_at((char *)"USER", nick, realname);
2005-05-01 12:27:27 +00:00
/*
* Now search the added entry to update the data
*/
for (tmpu = users; tmpu; tmpu = tmpu->next) {
if ((strcmp(tmpu->server, CFG.myfqdn) == 0) && (strcmp(tmpu->name, nick) == 0) && (strcmp(tmpu->realname, realname) == 0)) {
/*
* Oke, found
*/
2006-02-13 19:26:30 +00:00
tmpu->pid = atoi(pid);
tmpu->pointer = buffer_head;
tmpu->sysop = sys;
2005-05-01 13:35:43 +00:00
usrchg = TRUE;
srvchg = TRUE;
Syslog('c', "Connected user %s (%s) with chatserver, sysop %s", realname, pid, sys ? "True":"False");
2005-05-01 12:27:27 +00:00
/*
* Now put welcome message into the ringbuffer and report success.
*/
temp = calloc(81, sizeof(char));
snprintf(temp, 200, "MBSE BBS v%s chat server; type /help for help", VERSION);
system_msg(tmpu->pid, temp);
snprintf(temp, 200, "Welcome to the Internet BBS Chat Network");
system_msg(tmpu->pid, temp);
2006-02-06 14:32:25 +00:00
snprintf(temp, 200, "Current connected servers:");
system_msg(tmpu->pid, temp);
2005-05-01 12:27:27 +00:00
for (sl = servers; sl; sl = sl->next) {
snprintf(temp, 200, " %s (%d user%s)", sl->fullname, sl->users, (sl->users == 1) ? "":"s");
system_msg(tmpu->pid, temp);
2005-05-01 12:27:27 +00:00
count += sl->users;
}
snprintf(temp, 200, "There %s %d user%s connected", (count != 1)?"are":"is", count, (count != 1)?"s":"");
system_msg(tmpu->pid, temp);
2005-08-29 21:03:28 +00:00
snprintf(buf, 200, "100:0;");
free(realname);
free(nick);
free(temp);
return;
2005-05-01 12:27:27 +00:00
}
}
free(realname);
free(nick);
2005-08-29 21:03:28 +00:00
snprintf(buf, 200, "100:1,Too many users connected;");
return;
2003-03-24 19:44:38 +00:00
}
void chat_close_r(char *data, char *buf)
2003-03-24 19:44:38 +00:00
{
char *pid;
2005-05-01 12:27:27 +00:00
usr_list *tmpu;
2003-03-24 19:44:38 +00:00
Syslog('c', "CCLO:%s", data);
2003-03-24 19:44:38 +00:00
pid = strtok(data, ",");
pid = strtok(NULL, ";");
2005-04-20 16:59:32 +00:00
2005-05-01 12:27:27 +00:00
for (tmpu = users; tmpu; tmpu = tmpu->next) {
if (tmpu->pid == atoi(pid)) {
/*
* Remove from IBC network
*/
send_at((char *)"QUIT", tmpu->name, (char *)"Leaving chat");
2005-05-01 12:27:27 +00:00
del_user(&users, CFG.myfqdn, tmpu->name);
Syslog('c', "Closing chat for pid %s", pid);
2005-09-11 13:07:42 +00:00
snprintf(buf, 81, "100:0;");
return;
2005-05-01 12:27:27 +00:00
}
}
2006-02-13 19:26:30 +00:00
Syslog('c', "Pid %s was not connected to chatserver");
2005-09-11 13:07:42 +00:00
snprintf(buf, 81, "100:1,*** ERROR - Not connected to server;");
return;
2003-03-24 19:44:38 +00:00
}
void chat_put_r(char *data, char *buf)
2003-03-24 19:44:38 +00:00
{
2006-03-06 20:30:09 +00:00
char *p, *q, *pid, *msg, *cmd, *mbuf, *flags, temp[81];
2006-02-04 16:30:48 +00:00
int first, count, owner = FALSE, found;
2005-05-01 12:27:27 +00:00
usr_list *tmpu, *tmp;
2005-04-23 14:27:52 +00:00
chn_list *tmpc;
2003-03-24 19:44:38 +00:00
2003-04-02 21:36:47 +00:00
if (IsSema((char *)"upsalarm")) {
snprintf(buf, 81, "100:2,1,*** Power alarm, running on UPS;");
return;
2003-04-02 21:36:47 +00:00
}
2003-04-03 20:51:19 +00:00
if (s_bbsopen == FALSE) {
snprintf(buf, 81, "100:2,1,*** The BBS is closed now;");
return;
2003-04-03 20:51:19 +00:00
}
2003-03-24 19:44:38 +00:00
pid = strtok(data, ",");
pid = strtok(NULL, ",");
msg = xstrcpy(cldecode(strtok(NULL, ";")));
mbuf = calloc(200, sizeof(char));
2003-03-24 19:44:38 +00:00
2005-05-01 12:27:27 +00:00
for (tmpu = users; tmpu; tmpu = tmpu->next) {
if (tmpu->pid == atoi(pid)) {
2003-03-24 19:44:38 +00:00
if (msg[0] == '/') {
/*
2006-02-04 16:30:48 +00:00
* A command, process this but first se if we are in a channel
* and own the channel. This gives us more power.
2003-03-24 19:44:38 +00:00
*/
2006-02-04 16:30:48 +00:00
if (strlen(tmpu->channel)) {
for (tmpc = channels; tmpc; tmpc = tmpc->next) {
if (((strcmp(tmpu->nick, tmpc->owner) == 0) || (strcmp(tmpu->name, tmpc->owner) == 0)) &&
(strcmp(tmpu->server, tmpc->server) == 0)) {
owner = TRUE;
}
}
Syslog('c', "IBC: process command, in channel %s and we are %sthe owner", tmpu->channel, owner ? "":"not ");
}
2003-03-24 19:44:38 +00:00
if (strncasecmp(msg, "/help", 5) == 0) {
2006-02-04 16:59:26 +00:00
chat_help(atoi(pid), owner);
2003-04-01 21:41:36 +00:00
goto ack;
} else if (strncasecmp(msg, "/echo", 5) == 0) {
snprintf(mbuf, 200, "%s", msg);
system_msg(tmpu->pid, mbuf);
goto ack;
2003-04-03 20:51:19 +00:00
} else if ((strncasecmp(msg, "/exit", 5) == 0) ||
2003-04-01 21:41:36 +00:00
(strncasecmp(msg, "/quit", 5) == 0) ||
(strncasecmp(msg, "/bye", 4) == 0)) {
2006-02-04 16:30:48 +00:00
if (strlen(tmpu->channel)) {
/*
* If in a channel, leave channel first
*/
part(tmpu->pid, (char *)"Quitting");
snprintf(mbuf, 81, "Goodbye");
system_msg(tmpu->pid, mbuf);
}
2003-04-02 21:36:47 +00:00
goto hangup;
2003-04-03 20:51:19 +00:00
} else if ((strncasecmp(msg, "/join", 5) == 0) ||
(strncasecmp(msg, "/j ", 3) == 0)) {
2003-03-24 19:44:38 +00:00
cmd = strtok(msg, " \0");
cmd = strtok(NULL, "\0");
if ((cmd == NULL) || (cmd[0] != '#') || (strcmp(cmd, "#") == 0)) {
snprintf(mbuf, 200, "** Try /join #channel");
system_msg(tmpu->pid, mbuf);
2005-05-01 12:27:27 +00:00
} else if (strlen(tmpu->channel)) {
snprintf(mbuf, 200, "** Cannot join while in a channel");
system_msg(tmpu->pid, mbuf);
2005-05-01 12:27:27 +00:00
} else {
join(tmpu->pid, cmd, tmpu->sysop);
}
2003-04-03 20:51:19 +00:00
chat_dump();
2003-04-01 21:41:36 +00:00
goto ack;
2003-04-03 20:51:19 +00:00
} else if (strncasecmp(msg, "/list", 5) == 0) {
first = TRUE;
2005-04-23 14:27:52 +00:00
for (tmpc = channels; tmpc; tmpc = tmpc->next) {
if (first) {
snprintf(mbuf, 200, "Cnt Channel name Channel topic");
system_msg(tmpu->pid, mbuf);
snprintf(mbuf, 200, "--- -------------------- ------------------------------------------------------");
system_msg(tmpu->pid, mbuf);
2005-04-23 14:27:52 +00:00
}
first = FALSE;
2006-03-06 20:30:09 +00:00
q = calloc(81, sizeof(char));
snprintf(q, 81, "%3d %-20s ", tmpc->users, tmpc->name);
p = xstrcpy(q);
p = xstrcat(p, tmpc->topic);
system_msg(tmpu->pid, p);
free(p);
free(q);
2003-04-03 20:51:19 +00:00
}
if (first) {
snprintf(mbuf, 200, "No active channels to list");
system_msg(tmpu->pid, mbuf);
2003-04-03 20:51:19 +00:00
}
goto ack;
} else if (strncasecmp(msg, "/names", 6) == 0) {
2005-05-01 12:27:27 +00:00
if (strlen(tmpu->channel)) {
snprintf(mbuf, 200, "Present in channel %s:", tmpu->channel);
system_msg(tmpu->pid, mbuf);
snprintf(mbuf, 200, "Nick Real name Flags");
system_msg(tmpu->pid, mbuf);
2006-02-04 16:30:48 +00:00
snprintf(mbuf, 200, "---------------------------------------- ------------------------------ -----");
system_msg(tmpu->pid, mbuf);
count = 0;
2005-04-27 21:09:23 +00:00
for (tmp = users; tmp; tmp = tmp->next) {
2005-05-01 12:27:27 +00:00
if (strcmp(tmp->channel, tmpu->channel) == 0) {
2006-02-04 16:30:48 +00:00
/*
* Get channel flags
*/
flags = xstrcpy((char *)"--");
for (tmpc = channels; tmpc; tmpc = tmpc->next) {
if (strcmp(tmpc->name, tmpu->channel) == 0) {
if (((strcmp(tmpc->owner, tmp->nick) == 0) || (strcmp(tmpc->owner, tmp->name) == 0)) &&
(strcmp(tmpc->server, tmp->server) == 0)) {
flags[0] = 'O';
}
}
}
if (tmp->sysop)
flags[1] = 'S';
2005-08-29 21:03:28 +00:00
snprintf(temp, 81, "%s@%s", tmp->nick, tmp->server);
2006-02-04 16:30:48 +00:00
snprintf(mbuf, 200, "%-40s %-30s %s", temp, tmp->realname, flags);
system_msg(tmpu->pid, mbuf);
2005-04-27 21:09:23 +00:00
count++;
2006-02-04 16:30:48 +00:00
free(flags);
2005-04-27 21:09:23 +00:00
}
}
snprintf(mbuf, 200, "%d user%s in this channel", count, (count == 1) ?"":"s");
system_msg(tmpu->pid, mbuf);
2005-05-01 12:27:27 +00:00
} else {
snprintf(mbuf, 200, "** Not in a channel");
system_msg(tmpu->pid, mbuf);
2005-05-01 12:27:27 +00:00
}
goto ack;
2003-04-03 20:51:19 +00:00
} else if (strncasecmp(msg, "/nick", 5) == 0) {
cmd = strtok(msg, " \0");
cmd = strtok(NULL, "\0");
2005-04-20 16:59:32 +00:00
if ((cmd == NULL) || (strlen(cmd) == 0) || (strlen(cmd) > 9)) {
snprintf(mbuf, 200, "** Nickname must be between 1 and 9 characters");
2003-04-03 20:51:19 +00:00
} else {
2005-04-22 19:40:05 +00:00
found = FALSE;
for (tmp = users; tmp; tmp = tmp->next) {
if ((strcmp(tmp->name, cmd) == 0) || (strcmp(tmp->nick, cmd) == 0)) {
found = TRUE;
}
}
if (!found ) {
2005-05-01 12:27:27 +00:00
strncpy(tmpu->nick, cmd, 9);
snprintf(mbuf, 200, "Nick set to \"%s\"", cmd);
system_msg(tmpu->pid, mbuf);
send_nick(tmpu->nick, tmpu->name, tmpu->realname);
2005-05-01 12:27:27 +00:00
usrchg = TRUE;
chat_dump();
goto ack;
2005-04-22 19:40:05 +00:00
}
snprintf(mbuf, 200, "Can't set nick");
2005-04-22 19:40:05 +00:00
}
system_msg(tmpu->pid, mbuf);
2003-04-03 20:51:19 +00:00
chat_dump();
goto ack;
} else if (strncasecmp(msg, "/part", 5) == 0) {
2003-04-01 21:41:36 +00:00
cmd = strtok(msg, " \0");
Syslog('c', "\"%s\"", cmd);
2003-04-01 21:41:36 +00:00
cmd = strtok(NULL, "\0");
Syslog('c', "\"%s\"", printable(cmd, 0));
2005-05-01 12:27:27 +00:00
if (part(tmpu->pid, cmd ? cmd : (char *)"Quitting") == FALSE) {
snprintf(mbuf, 200, "** Not in a channel");
system_msg(tmpu->pid, mbuf);
2005-05-01 12:27:27 +00:00
}
2003-04-03 20:51:19 +00:00
chat_dump();
goto ack;
} else if (strncasecmp(msg, "/topic", 6) == 0) {
2005-05-01 12:27:27 +00:00
if (strlen(tmpu->channel)) {
snprintf(mbuf, 200, "** Internal system error");
2005-04-23 14:27:52 +00:00
for (tmpc = channels; tmpc; tmpc = tmpc->next) {
2005-05-01 12:27:27 +00:00
if (strcmp(tmpu->channel, tmpc->name) == 0) {
2006-02-04 16:52:53 +00:00
if (owner) {
2005-04-23 14:27:52 +00:00
cmd = strtok(msg, " \0");
cmd = strtok(NULL, "\0");
if ((cmd == NULL) || (strlen(cmd) == 0) || (strlen(cmd) > 54)) {
snprintf(mbuf, 200, "** Topic must be between 1 and 54 characters");
2005-04-23 14:27:52 +00:00
} else {
strncpy(tmpc->topic, cmd, 54);
snprintf(mbuf, 200, "Topic set to \"%s\"", cmd);
2006-03-06 16:34:26 +00:00
p = xstrcpy((char *)"TOPIC ");
p = xstrcat(p, tmpc->name);
p = xstrcat(p, (char *)" ");
p = xstrcat(p, tmpc->topic);
p = xstrcat(p, (char *)"\r\n");
send_all(p);
free(p);
2005-04-23 14:27:52 +00:00
}
} else {
snprintf(mbuf, 200, "** You are not the channel owner");
2005-04-23 14:27:52 +00:00
}
break;
}
}
2005-05-01 12:27:27 +00:00
} else {
snprintf(mbuf, 200, "** Not in a channel");
2005-05-01 12:27:27 +00:00
}
system_msg(tmpu->pid, mbuf);
chat_dump();
goto ack;
2003-04-03 20:51:19 +00:00
} else {
/*
* If still here, the command was not recognized.
*/
cmd = strtok(msg, " \t\r\n\0");
snprintf(mbuf, 200, "*** \"%s\" :Unknown command", cmd+1);
system_msg(tmpu->pid, mbuf);
2003-04-01 21:41:36 +00:00
goto ack;
2003-03-24 19:44:38 +00:00
}
}
2005-05-01 12:27:27 +00:00
if (strlen(tmpu->channel) == 0) {
2003-03-24 19:44:38 +00:00
/*
* Trying messages while not in a channel
*/
snprintf(mbuf, 200, "** No channel joined. Try /join #channel");
system_msg(tmpu->pid, mbuf);
2003-04-01 21:41:36 +00:00
goto ack;
} else {
2005-05-01 12:27:27 +00:00
chat_msg(tmpu->channel, tmpu->nick, msg);
/*
* Send message to all links but not the #sysop channel
*/
2006-03-06 16:34:26 +00:00
if (strcmp(tmpu->channel, "#sysop")) {
p = xstrcpy((char *)"PRIVMSG ");
p = xstrcat(p, tmpu->channel);
p = xstrcat(p, (char *)" <");
p = xstrcat(p, tmpu->nick);
p = xstrcat(p, (char *)"> ");
p = xstrcat(p, msg);
p = xstrcat(p, (char *)"\r\n");
send_all(p);
free(p);
}
2003-03-24 19:44:38 +00:00
}
2003-04-01 21:41:36 +00:00
goto ack;
2003-03-24 19:44:38 +00:00
}
}
2006-02-06 12:26:03 +00:00
2006-02-06 12:32:24 +00:00
Syslog('+', "Pid %s was not connected to chatserver", pid);
2005-08-29 21:03:28 +00:00
snprintf(buf, 200, "100:2,1,*** ERROR - Not connected to server;");
free(msg);
free(mbuf);
return;
2003-04-01 21:41:36 +00:00
ack:
2005-08-29 21:03:28 +00:00
snprintf(buf, 200, "100:0;");
free(msg);
free(mbuf);
return;
2003-04-02 21:36:47 +00:00
hangup:
2005-08-29 21:03:28 +00:00
snprintf(buf, 200, "100:2,1,Disconnecting;");
free(msg);
free(mbuf);
return;
2003-03-24 19:44:38 +00:00
}
2003-04-03 20:51:19 +00:00
/*
* Check for a message for the user. Return the message or signal that
* nothing is there to display.
*/
void chat_get_r(char *data, char *buf)
2003-03-24 19:44:38 +00:00
{
2006-03-06 16:34:26 +00:00
char *pid, *p;
2005-05-01 12:27:27 +00:00
usr_list *tmpu;
2003-04-02 21:36:47 +00:00
if (IsSema((char *)"upsalarm")) {
2005-08-29 21:03:28 +00:00
snprintf(buf, 200, "100:2,1,*** Power failure, running on UPS;");
return;
2003-04-03 20:51:19 +00:00
}
if (s_bbsopen == FALSE) {
2005-08-29 21:03:28 +00:00
snprintf(buf, 200, "100:2,1,*** The BBS is closed now;");
return;
2003-04-02 21:36:47 +00:00
}
2003-03-24 19:44:38 +00:00
pid = strtok(data, ",");
pid = strtok(NULL, ";");
2005-05-01 12:27:27 +00:00
for (tmpu = users; tmpu; tmpu = tmpu->next) {
if (atoi(pid) == tmpu->pid) {
while (tmpu->pointer != buffer_head) {
if (tmpu->pointer < MAXMESSAGES)
tmpu->pointer++;
else
tmpu->pointer = 0;
if (tmpu->pid == chat_messages[tmpu->pointer].topid) {
/*
* Message is for us
*/
2006-03-06 16:34:26 +00:00
p = xstrcpy((char *)"100:2,0,");
p = xstrcat(p, clencode(chat_messages[tmpu->pointer].message));
p = xstrcat(p, (char *)";");
strncpy(buf, p, 200);
free(p);
return;
2005-05-01 12:27:27 +00:00
}
}
2005-08-29 21:03:28 +00:00
snprintf(buf, 200, "100:0;");
return;
2005-05-01 12:27:27 +00:00
}
}
2005-08-29 21:03:28 +00:00
snprintf(buf, 200, "100:2,1,*** ERROR - Not connected to server;");
return;
2003-04-02 21:36:47 +00:00
}
/*
* Check for sysop present for forced chat
*/
void chat_checksysop_r(char *data, char *buf)
2003-04-02 21:36:47 +00:00
{
char *pid;
2005-05-01 12:27:27 +00:00
usr_list *tmpu;
2003-04-02 21:36:47 +00:00
pid = strtok(data, ",");
pid = strtok(NULL, ";");
2006-02-13 19:26:30 +00:00
2003-04-02 21:36:47 +00:00
if (reg_ispaging(pid)) {
Syslog('c', "Check sysopchat for pid %s, user has paged", pid);
2003-04-02 21:36:47 +00:00
2006-02-13 19:26:30 +00:00
/*
* Now check if sysop is present in the sysop channel
*/
for (tmpu = users; tmpu; tmpu = tmpu->next) {
2005-05-01 12:27:27 +00:00
if (atoi(pid) != tmpu->pid) {
2006-02-13 19:26:30 +00:00
if (strlen(tmpu->channel) && (strcasecmp(tmpu->channel, "#sysop") == 0) && tmpu->sysop) {
Syslog('c', "Sending ACK on check");
2005-08-29 21:03:28 +00:00
snprintf(buf, 20, "100:1,1;");
2005-05-01 12:27:27 +00:00
reg_sysoptalk(pid);
return;
2005-05-01 12:27:27 +00:00
}
}
}
2003-04-02 21:36:47 +00:00
}
2005-08-29 21:03:28 +00:00
snprintf(buf, 20, "100:1,0;");
return;
2003-03-24 19:44:38 +00:00
}