Updates for the chatserver

This commit is contained in:
Michiel Broek
2003-03-24 19:44:38 +00:00
parent 3d157ec16a
commit c09bebade4
14 changed files with 549 additions and 107 deletions

View File

@@ -80,10 +80,10 @@ depend:
# Dependencies generated by make depend
callstat.o: ../config.h libs.h ../lib/structs.h taskutil.h callstat.h
scanout.o: ../config.h libs.h ../lib/structs.h taskutil.h scanout.h
taskcomm.o: ../config.h libs.h ../lib/structs.h taskstat.h taskregs.h taskdisk.h taskinfo.h taskutil.h taskcomm.h
taskcomm.o: ../config.h libs.h ../lib/structs.h taskstat.h taskregs.h taskdisk.h taskinfo.h taskutil.h taskchat.h taskcomm.h
taskinfo.o: ../config.h libs.h ../lib/structs.h taskinfo.h
taskstat.o: ../config.h libs.h ../lib/structs.h ../lib/mberrors.h taskstat.h callstat.h outstat.h taskutil.h
mbtask.o: ../config.h libs.h ../lib/structs.h ../paths.h ../lib/mberrors.h signame.h taskstat.h taskutil.h taskregs.h taskcomm.h callstat.h outstat.h ../lib/nodelist.h ports.h calllist.h ping.h mbtask.h
mbtask.o: ../config.h libs.h ../lib/structs.h ../paths.h ../lib/mberrors.h signame.h taskstat.h taskutil.h taskregs.h taskcomm.h callstat.h outstat.h ../lib/nodelist.h ports.h calllist.h ping.h taskchat.h mbtask.h
outstat.o: ../config.h libs.h ../lib/structs.h ../lib/mberrors.h taskutil.h taskstat.h scanout.h ../lib/nodelist.h callstat.h ports.h outstat.h
signame.o: ../config.h signame.h
taskdisk.o: ../config.h libs.h ../lib/structs.h taskdisk.h taskutil.h
@@ -93,5 +93,5 @@ ports.o: ../config.h libs.h ../lib/structs.h taskutil.h ../lib/nodelist.h ports.
calllist.o: ../config.h libs.h ../lib/structs.h taskstat.h taskutil.h callstat.h outstat.h mbtask.h calllist.h
ping.o: ../config.h libs.h ../lib/structs.h ../lib/mberrors.h taskstat.h taskutil.h ping.h
crc.o: ../config.h libs.h crc.h
taskchat.o: ../config.h libs.h ../lib/structs.h taskchat.h
taskchat.o: ../config.h libs.h ../lib/structs.h taskutil.h taskchat.h
# End of generated dependencies

View File

@@ -44,6 +44,7 @@
#include "ports.h"
#include "calllist.h"
#include "ping.h"
#include "taskchat.h"
#include "mbtask.h"
@@ -1315,6 +1316,7 @@ int main(int argc, char **argv)
initnl();
load_ports();
check_ports();
chat_init();
/*
* Now that init is complete and this program is locked, it is

View File

@@ -31,6 +31,307 @@
#include "../config.h"
#include "libs.h"
#include "../lib/structs.h"
#include "taskutil.h"
#include "taskregs.h"
#include "taskchat.h"
#define MAXCHANNELS 100 /* Maximum chat channels */
#define MAXMESSAGES 100 /* Maximum ringbuffer for messages */
typedef enum {CH_FREE, CH_PRIVATE, CH_PUBLIC} CHANNELTYPE;
/*
* Users connected to the chatserver.
*/
typedef struct _ch_user_rec {
pid_t pid; /* User's pid */
char name[36]; /* His name used (may become nick) */
time_t connected; /* Time connected */
int channel; /* Connected channel or -1 */
int pointer; /* Message pointer */
unsigned chatting : 1; /* Is chatting in a channel */
unsigned chanop : 1; /* Is a chanop */
} _chat_users;
/*
* 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;
/*
* List of banned users from a channel. This is a dynamic list.
*/
typedef struct _banned {
int channel; /* Channel the user is banned from */
char user[36]; /* The user who is banned */
} banned_users;
/*
* The buffers
*/
_chat_messages chat_messages[MAXMESSAGES];
_chat_users chat_users[MAXCLIENT];
int buffer_head = 0; /* Messages buffer head */
extern struct sysconfig CFG; /* System configuration */
/*
* Put a system message into the chatbuffer
*/
void system_msg(pid_t, char *);
void system_msg(pid_t pid, char *msg)
{
if (buffer_head < MAXMESSAGES)
buffer_head++;
else
buffer_head = 0;
Syslog('-', "system_msg(%d, %s) ptr=%d", pid, msg, buffer_head);
memset(&chat_messages[buffer_head], 0, sizeof(_chat_messages));
chat_messages[buffer_head].topid = pid;
sprintf(chat_messages[buffer_head].fromname, "Server");
strncpy(chat_messages[buffer_head].message, msg, 80);
chat_messages[buffer_head].posted = time(NULL);
}
/*
* Show help
*/
void chat_help(pid_t);
void chat_help(pid_t pid)
{
system_msg(pid, (char *)"Topics available:");
system_msg(pid, (char *)"");
system_msg(pid, (char *)" EXIT HELP");
}
void chat_init(void)
{
memset(&chat_users, 0, sizeof(chat_users));
memset(&chat_messages, 0, sizeof(chat_messages));
}
/*
* Connect a session to the chatserver.
*/
char *chat_connect(char *data)
{
char *pid, *usr;
static char buf[200];
int i, j, count = 0;
Syslog('-', "CCON:%s", data);
memset(&buf, 0, sizeof(buf));
/*
* Search free userslot
*/
for (i = 0; i < MAXCLIENT; i++) {
if (chat_users[i].pid == 0) {
/*
* Oke, found
*/
pid = strtok(data, ","); /* Should be 2 */
pid = strtok(NULL, ","); /* The pid */
usr = strtok(NULL, ";"); /* Username */
chat_users[i].pid = atoi(pid);
strncpy(chat_users[i].name, usr, 36);
chat_users[i].connected = time(NULL);
chat_users[i].pointer = buffer_head;
chat_users[i].channel = -1;
Syslog('-', "Connected user %s (%s) with chatserver, slot %d", usr, pid, i);
/*
* Now put welcome message into the ringbuffer and report success.
*/
sprintf(buf, "MBSE BBS v%s chat server; type /help for help", VERSION);
system_msg(chat_users[i].pid, buf);
sprintf(buf, "Welcome to the %s chat network", CFG.bbs_name);
system_msg(chat_users[i].pid, buf);
for (j = 0; j < MAXCLIENT; j++)
if (chat_users[j].pid)
count++;
sprintf(buf, "There %s %d user%s connected", (count != 1)?"are":"is", count, (count != 1)?"s":"");
system_msg(chat_users[i].pid, buf);
sprintf(buf, "100:0;");
return buf;
}
}
sprintf(buf, "100:1,Too many users connected;");
return buf;
}
char *chat_close(char *data)
{
static char buf[200];
char *pid;
int i;
Syslog('-', "CCLO:%s", data);
memset(&buf, 0, sizeof(buf));
pid = strtok(data, ",");
pid = strtok(NULL, ";");
for (i = 0; i < MAXCLIENT; i++) {
if (chat_users[i].pid == atoi(pid)) {
Syslog('-', "Closing chat for pid %s, slot %d", pid, i);
memset(&chat_users[i], 0, sizeof(_chat_users));
sprintf(buf, "100:0;");
return buf;
}
}
Syslog('-', "Pid %s was not connected to chatserver");
sprintf(buf, "100:1,ERROR - Not connected to server;");
return buf;
}
char *chat_put(char *data)
{
static char buf[200];
char *pid, *msg, *cmd;
int i;
Syslog('-', "CPUT:%s", data);
memset(&buf, 0, sizeof(buf));
pid = strtok(data, ",");
pid = strtok(NULL, ",");
msg = strtok(NULL, "\0");
msg[strlen(msg)-1] = '\0';
for (i = 0; i < MAXCLIENT; i++) {
if (chat_users[i].pid == atoi(pid)) {
/*
* We are connected and known, first send the input back to ourself.
*/
system_msg(chat_users[i].pid, msg);
if (msg[0] == '/') {
/*
* A command, process this
*/
if (strncasecmp(msg, "/help", 5) == 0) {
chat_help(atoi(pid));
sprintf(buf, "100:0;");
return buf;
}
if (strncasecmp(msg, "/exit", 5) == 0) {
/*
* Just send messages, the client should later do a
* real disconnect.
*/
sprintf(buf, "Goodbye");
system_msg(chat_users[i].pid, buf);
sprintf(buf, "100:0;");
return buf;
}
if (strncasecmp(msg, "/join", 5) == 0) {
cmd = strtok(msg, " \0");
Syslog('-', "\"%s\"", cmd);
cmd = strtok(NULL, "\0");
Syslog('-', "\"%s\"", cmd);
if ((cmd == NULL) || (cmd[0] != '#') || (strcmp(cmd, "#") == 0)) {
sprintf(buf, "Try /join #channel");
system_msg(chat_users[i].pid, buf);
} else {
Syslog('-', "Trying to join channel %s", cmd);
}
sprintf(buf, "100:0;");
return buf;
}
/*
* If still here, the command was not recognized.
*/
cmd = strtok(msg, " \t\r\n\0");
sprintf(buf, "%s :Unknown command", cmd+1);
system_msg(chat_users[i].pid, buf);
sprintf(buf, "100:0;");
return buf;
}
if (chat_users[i].channel == -1) {
/*
* Trying messages while not in a channel
*/
sprintf(buf, "No channel joined. Try /join #channel");
system_msg(chat_users[i].pid, buf);
sprintf(buf, "100:0;");
return buf;
}
sprintf(buf, "100:0;");
return buf;
}
}
Syslog('-', "Pid %s was not connected to chatserver");
sprintf(buf, "100:1,ERROR - Not connected to server;");
return buf;
}
char *chat_get(char *data)
{
static char buf[200];
char *pid;
int i;
Syslog('-', "CGET:%s", data);
memset(&buf, 0, sizeof(buf));
pid = strtok(data, ",");
pid = strtok(NULL, ";");
for (i = 0; i < MAXCLIENT; i++) {
if (atoi(pid) == chat_users[i].pid) {
while (chat_users[i].pointer != buffer_head) {
if (chat_users[i].pointer < MAXMESSAGES)
chat_users[i].pointer++;
else
chat_users[i].pointer = 0;
if (chat_users[i].pid == chat_messages[chat_users[i].pointer].topid) {
/*
* Message is for us.
*/
sprintf(buf, "100:1,%s;", chat_messages[chat_users[i].pointer].message);
Syslog('-', "%s", buf);
return buf;
}
}
sprintf(buf, "100:0;");
return buf;
}
}
sprintf(buf, "100:1,ERROR - Not connected to server;");
return buf;
}

View File

@@ -3,5 +3,10 @@
/* $Id$ */
void chat_init(void);
char *chat_connect(char *);
char *chat_close(char *);
char *chat_put(char *);
char *chat_get(char *);
#endif

View File

@@ -36,6 +36,7 @@
#include "taskdisk.h"
#include "taskinfo.h"
#include "taskutil.h"
#include "taskchat.h"
#include "taskcomm.h"
@@ -239,14 +240,10 @@ char *exe_cmd(char *in)
}
/*
* The chat commands
* Check for personal message
*
* Used channels: -1 Personal messages between ordinary users.
* 0 Sysop/user chat
* 1..99 Chatting channels
*
* CIPM:1,pid; (Is personal/chat message present)
* 100:3,channel,fromname,message;
* CIPM:1,pid; (Is personal message present)
* 100:2,fromname,message;
* 100:0;
*/
if (strncmp(cmd, "CIPM", 4) == 0) {
@@ -254,7 +251,7 @@ char *exe_cmd(char *in)
}
/*
* CSPM:3,channel,fromuser,touser,text; (Send personal/chat message).
* CSPM:3,fromuser,touser,text; (Send personal message).
* 100:1,n; n: 1=donotdisturb 2=buffer full 3=error
* 100:0;
*/
@@ -296,10 +293,63 @@ char *exe_cmd(char *in)
return obuf;
}
/*
* Check for sysop page (from mbmon)
*
* CCKP:0;
* 100:3,pid,1,reason; Page is active
* 100:3,pid,0,reason; Page is canceled, but user still online
* 100:0; No page active
*/
if (strncmp(cmd, "CCKP", 4) == 0) {
return reg_checkpage(token);
}
/*
* Connect to chatserver
*
* CCON:2,pid,username; Connect to chatserver with username
* 100:1,error; If error
* 100:0; Ok
*/
if (strncmp(cmd, "CCON", 4) == 0) {
return chat_connect(token);
}
/*
* Close chat session
*
* CCLO:1,pid; Leave chatserver
* 100:1,error; Error
* 100:0; Ok
*/
if (strncmp(cmd, "CCLO", 4) == 0) {
return chat_close(token);
}
/*
* Put message on server
*
* CPUT:2,pid,message; Put message on server
* 100:1,error; Error
* 100:0; Ok
*/
if (strncmp(cmd, "CPUT", 4) == 0) {
return chat_put(token);
}
/*
* Get message from server
*
* CGET:1,pid; Get message from server
* 100:1,message; If message present
* 100:0; No message
*/
if (strncmp(cmd, "CGET", 4) == 0) {
return chat_get(token);
}
/*
* The G(lobal) commands.
*

View File

@@ -406,12 +406,11 @@ char *reg_ipm(char *data)
return buf;
reginfo[rec].lastcon = time(NULL);
if (!reginfo[rec].ismsg || (reginfo[rec].channel != -1))
if (!reginfo[rec].ismsg)
return buf;
buf[0] = '\0';
sprintf(buf, "100:3,%d,%s,%s;", reginfo[rec].channel,
reginfo[rec].fname[reginfo[rec].ptr_out], reginfo[rec].msg[reginfo[rec].ptr_out]);
sprintf(buf, "100:2,%s,%s;", reginfo[rec].fname[reginfo[rec].ptr_out], reginfo[rec].msg[reginfo[rec].ptr_out]);
if (reginfo[rec].ptr_out < RB)
reginfo[rec].ptr_out++;
else
@@ -419,8 +418,7 @@ char *reg_ipm(char *data)
if (reginfo[rec].ptr_out == reginfo[rec].ptr_in)
reginfo[rec].ismsg = FALSE;
Syslog('+', "reg_ipm: ch=%d in=%d out=%d ismsg=%d", reginfo[rec].channel,
reginfo[rec].ptr_in, reginfo[rec].ptr_out, reginfo[rec].ismsg);
Syslog('+', "reg_ipm: in=%d out=%d ismsg=%d", reginfo[rec].ptr_in, reginfo[rec].ptr_out, reginfo[rec].ismsg);
return buf;
}
@@ -432,41 +430,33 @@ char *reg_ipm(char *data)
*/
int reg_spm(char *data)
{
char *cnt, *ch, *from, *too, *txt, *log;
int i, error = 0;
char *cnt, *from, *too, *txt, *log;
int i;
cnt = strtok(data, ",");
ch = strtok(NULL, ",");
from = strtok(NULL, ",");
too = strtok(NULL, ",");
txt = strtok(NULL, "\0");
txt[strlen(txt)-1] = '\0';
Syslog('-', "SIPM:%s,%s,%s,%s,%s;", cnt, ch, from, too, txt);
log = calloc(PATH_MAX, sizeof(char));
sprintf(log, "%s/log/%s", getenv("MBSE_ROOT"), CFG.chat_log);
Syslog('-', "SIPM:%s,%s,%s,%s;", cnt, from, too, txt);
for (i = 0; i < MAXCLIENT; i++) {
/*
* Personal messages and sysop/user chat messages.
*/
if (reginfo[i].pid &&
(((strcasecmp(reginfo[i].uname, too) == 0) && (atoi(ch) == -1)) || (atoi(ch) == 0)) &&
(atoi(ch) == reginfo[i].channel)) {
if (reginfo[i].pid && (strcasecmp(reginfo[i].uname, too) == 0)) {
/*
* If the in and out pointers are the same and the
* message present flag is still set, then this user
* can't get anymore new messages.
*/
if (reginfo[i].ismsg && (reginfo[i].ptr_in == reginfo[i].ptr_out)) {
error = 2;
return 2;
}
/*
* If user has the "do not distrurb" flag set, but the sysop ignore's this.
*/
if (reginfo[i].silent && (atoi(ch) == -1)) {
error = 1;
if (reginfo[i].silent) {
return 1;
}
/*
@@ -481,45 +471,18 @@ int reg_spm(char *data)
reginfo[i].ismsg = TRUE;
if (CFG.iAutoLog && strlen(CFG.chat_log)) {
ulog(log, (char *)"+", from, ch, txt);
log = calloc(PATH_MAX, sizeof(char));
sprintf(log, "%s/log/%s", getenv("MBSE_ROOT"), CFG.chat_log);
ulog(log, (char *)"+", from, (char *)"-1", txt);
free(log);
}
Syslog('+', "reg_spm: rec=%d in=%d out=%d ismsg=%d", i, reginfo[i].ptr_in, reginfo[i].ptr_out, reginfo[i].ismsg);
}
if ((atoi(ch) == -1) || (atoi(ch) == 0)) {
free(log);
return error;
}
/*
* Chat messages, they are send to each user that is chatting in the right channel.
*/
if (reginfo[i].pid && reginfo[i].chatting && reginfo[i].channel == atoi(ch)) {
if (reginfo[i].ismsg && (reginfo[i].ptr_in == reginfo[i].ptr_out)) {
Syslog('!', "reg_spm: buffer full for %s", reginfo[i].uname);
} else {
strncpy((char *)&reginfo[i].fname[reginfo[i].ptr_in], from, 35);
strncpy((char *)&reginfo[i].msg[reginfo[i].ptr_in], txt, 80);
if (reginfo[i].ptr_in < RB)
reginfo[i].ptr_in++;
else
reginfo[i].ptr_in = 0;
reginfo[i].ismsg = TRUE;
if (CFG.iAutoLog && strlen(CFG.chat_log)) {
ulog(log, (char *)"+", from, ch, txt);
}
Syslog('+', "reg_spm: user=%s in=%d out=%d ismsg=%d", reginfo[i].uname, reginfo[i].ptr_in,
reginfo[i].ptr_out, reginfo[i].ismsg);
}
return 0;
}
}
free(log);
if ((atoi(ch) == -1) || (atoi(ch) == 0))
return 3; // Error
return 0; // Ok
return 3; // Error, user not found
}

View File

@@ -51,8 +51,8 @@ int reg_timer(int, char *);
int reg_tty(char *);
int reg_user(char *);
int reg_silent(char *); /* Set/Reset do not disturb */
char *reg_ipm(char *); /* Check for personal/chat msg */
int reg_spm(char *); /* Send personal/chat message */
char *reg_ipm(char *); /* Check for personal message */
int reg_spm(char *); /* Send personal message */
char *reg_fre(void); /* Check if system is free */
char *get_reginfo(int); /* Get registration info */
int reg_sysop(char *); /* Registrate sysop presence */