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/mbsebbs/chat.c
2003-08-16 20:45:01 +00:00

399 lines
9.5 KiB
C

/*****************************************************************************
*
* $Id$
* Purpose ...............: Sysop to user chat utility
*
*****************************************************************************
* Copyright (C) 1997-2003
*
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*****************************************************************************/
#include "../config.h"
#include "../lib/libs.h"
#include "../lib/ansi.h"
#include "../lib/mbse.h"
#include "../lib/structs.h"
#include "../lib/users.h"
#include "../lib/records.h"
#include "../lib/common.h"
#include "../lib/clcomm.h"
#include "../lib/mberrors.h"
#include "chat.h"
#include "funcs.h"
#include "input.h"
#include "language.h"
#include "misc.h"
#include "whoson.h"
int chat_with_sysop = FALSE; /* Global sysop chat flag */
int chatting = FALSE; /* Global chatting flag */
char rbuf[50][80]; /* Chat receive buffer */ /* FIXME: must be a dynamic buffer */
int rpointer = 0; /* Chat receive pointer */
int rsize = 5; /* Chat receive size */
extern pid_t mypid;
void Showline(int, int, char *);
void DispMsg(char *);
void clrtoeol(void);
unsigned char testkey(int, int);
unsigned char testkey(int y, int x)
{
int rc;
unsigned char ch = 0;
Nopper();
locate(y, x);
fflush(stdout);
if ((ttyfd = open("/dev/tty", O_RDWR|O_NONBLOCK)) < 0) {
perror("open /dev/tty");
exit(MBERR_TTYIO_ERROR);
}
Setraw();
rc = Waitchar(&ch, 50);
if (rc == 1) {
if (ch == KEY_ESCAPE)
rc = Escapechar(&ch);
}
Unsetraw();
close(ttyfd);
if (rc == 1)
return ch;
else
return '\0';
}
/*
* Colorize the chat window
*/
void Showline(int y, int x, char *msg)
{
int i;
if (strlen(msg)) {
if (msg[0] == '<') {
locate(y, x);
colour(LIGHTCYAN, BLACK);
putchar('<');
colour(LIGHTBLUE, BLACK);
for (i = 1; i < strlen(msg); i++) {
if (msg[i] == '>') {
colour(LIGHTCYAN, BLACK);
putchar(msg[i]);
colour(CYAN, BLACK);
} else {
putchar(msg[i]);
}
}
} else if (msg[0] == '*') {
colour(LIGHTRED, BLACK);
mvprintw(y, x, msg);
} else {
colour(GREEN, BLACK);
mvprintw(y, x, msg);
}
}
}
/*
* Display received chat message in the chat window.
*/
void DispMsg(char *msg)
{
int i;
strncpy(rbuf[rpointer], msg, 80);
Showline(2 + rpointer, 1, rbuf[rpointer]);
if (rpointer == rsize) {
/*
* Scroll buffer
*/
for (i = 0; i <= rsize; i++) {
locate(i + 2, 1);
clrtoeol();
sprintf(rbuf[i], "%s", rbuf[i+1]);
Showline(i + 2, 1, rbuf[i]);
}
} else {
rpointer++;
}
fflush(stdout);
}
/*
* Clear to End Of Line
*/
void clrtoeol(void)
{
fprintf(stdout, ANSI_CLREOL);
}
/*
* Chat, if the parameters are not NULL, a connection with the named
* channel is made with the give username which will be forced to the
* used nick name. This mode is used for forced sysop chat.
* If the parameters are NULL, then it's up to the user what happens.
*/
void Chat(char *username, char *channel)
{
int curpos = 0, stop = FALSE, data, rc;
unsigned char ch;
char sbuf[81], resp[128], *cnt, *msg;
static char buf[200];
WhosDoingWhat(SYSOPCHAT);
clear();
rsize = exitinfo.iScreenLen - 5;
rpointer = 0;
if (username && channel) {
colour(LIGHTGREEN, BLACK);
/* *** Sysop is starting chat *** */
printf("\007%s\n\r", (char *) Language(59));
fflush(stdout);
sleep(1);
printf("\007");
fflush(stdout);
sleep(1);
printf("\007");
fflush(stdout);
Syslog('+', "Sysop chat started");
chat_with_sysop = TRUE;
} else {
Syslog('+', "User started chatting");
}
/*
* Setup the screen, this is only possible in ANSI mode.
*/
clear();
locate(1, 1);
colour(WHITE, BLUE);
clrtoeol();
mvprintw(1, 2, "MBSE BBS Chat Server");
sprintf(buf, "CCON,3,%d,%s,0;", mypid, exitinfo.Name);
Syslog('-', "> %s", buf);
if (socket_send(buf) == 0) {
strncpy(buf, socket_receive(), sizeof(buf)-1);
Syslog('-', "< %s", buf);
if (strncmp(buf, "100:1,", 6) == 0) {
cnt = strtok(buf, ",");
msg = strtok(NULL, "\0");
msg[strlen(msg)-1] = '\0';
colour(LIGHTRED, BLACK);
mvprintw(4, 1, msg);
sleep(2);
Pause();
chat_with_sysop = FALSE;
return;
}
}
locate(exitinfo.iScreenLen - 2, 1);
colour(WHITE, BLUE);
clrtoeol();
mvprintw(exitinfo.iScreenLen - 2, 2, "Chat, type \"/EXIT\" to exit");
colour(LIGHTGRAY, BLACK);
mvprintw(exitinfo.iScreenLen - 1, 1, ">");
memset(&sbuf, 0, sizeof(sbuf));
memset(&rbuf, 0, sizeof(rbuf));
/*
* If username and channelname are given, send the /nick and /join
* commands to the chatserver.
*/
if (username && channel) {
sprintf(buf, "CPUT:2,%d,/nick %s;", mypid, username);
if (socket_send(buf) == 0)
strcpy(buf, socket_receive());
sprintf(buf, "CPUT:2,%d,/join %s;", mypid, channel);
if (socket_send(buf) == 0)
strcpy(buf, socket_receive());
}
Syslog('-', "Start loop");
chatting = TRUE;
while (stop == FALSE) {
/*
* Check for new message, loop fast until no more data available.
*/
data = TRUE;
while (data) {
sprintf(buf, "CGET:1,%d;", mypid);
if (socket_send(buf) == 0) {
strncpy(buf, socket_receive(), sizeof(buf)-1);
if (strncmp(buf, "100:2,", 6) == 0) {
Syslog('-', "> CGET:1,%d;", mypid);
Syslog('-', "< %s", buf);
strncpy(resp, strtok(buf, ":"), 10); /* Should be 100 */
strncpy(resp, strtok(NULL, ","), 5); /* Should be 2 */
strncpy(resp, strtok(NULL, ","), 5); /* 1= fatal, chat ended */
rc = atoi(resp);
memset(&resp, 0, sizeof(resp));
strncpy(resp, strtok(NULL, "\0"), 80); /* The message */
resp[strlen(resp)-1] = '\0';
DispMsg(resp);
if (rc == 1) {
Syslog('+', "Chat server error: %s", resp);
stop = TRUE;
data = FALSE;
}
} else {
data = FALSE;
}
}
}
if (stop)
break;
/*
* Check for a pressed key, if so then process it
*/
ch = testkey(exitinfo.iScreenLen -1, curpos + 2);
if (isprint(ch)) {
if (curpos < 77) {
putchar(ch);
fflush(stdout);
sbuf[curpos] = ch;
curpos++;
} else {
putchar(7);
fflush(stdout);
}
} else if ((ch == KEY_BACKSPACE) || (ch == KEY_RUBOUT) || (ch == KEY_DEL)) {
if (curpos) {
curpos--;
sbuf[curpos] = '\0';
printf("\b \b");
} else {
putchar(7);
}
} else if ((ch == '\r') && curpos) {
sprintf(buf, "CPUT:2,%d,%s;", mypid, sbuf);
Syslog('-', "> %s", buf);
if (socket_send(buf) == 0) {
strcpy(buf, socket_receive());
Syslog('-', "< %s", buf);
if (strncmp(buf, "100:2,", 6) == 0) {
strncpy(resp, strtok(buf, ":"), 10); /* Should be 100 */
strncpy(resp, strtok(NULL, ","), 5); /* Should be 2 */
strncpy(resp, strtok(NULL, ","), 5); /* 1= fatal, chat ended */
rc = atoi(resp);
strncpy(resp, strtok(NULL, "\0"), 80); /* The message */
resp[strlen(resp)-1] = '\0';
DispMsg(resp);
if (rc == 1) {
Syslog('+', "Chat server error: %s", resp);
stop = TRUE;
}
}
}
curpos = 0;
memset(&sbuf, 0, sizeof(sbuf));
locate(exitinfo.iScreenLen - 1, 2);
clrtoeol();
mvprintw(exitinfo.iScreenLen - 1, 1, ">");
}
}
chatting = FALSE;
/*
* Before sending the close command, purge all outstanding messages.
*/
data = TRUE;
while (data) {
sprintf(buf, "CGET:1,%d;", mypid);
if (socket_send(buf) == 0) {
strncpy(buf, socket_receive(), sizeof(buf)-1);
if (strncmp(buf, "100:2,", 6) == 0) {
Syslog('-', "> CGET:1,%d;", mypid);
Syslog('-', "< %s", buf);
strncpy(resp, strtok(buf, ":"), 10); /* Should be 100 */
strncpy(resp, strtok(NULL, ","), 5); /* Should be 2 */
strncpy(resp, strtok(NULL, ","), 5); /* 1= fatal error */
rc = atoi(resp);
memset(&resp, 0, sizeof(resp));
strncpy(resp, strtok(NULL, "\0"), 80); /* The message */
resp[strlen(resp)-1] = '\0';
DispMsg(resp);
if (rc == 1) {
Syslog('+', "Chat server error: %s", resp);
data = FALSE; /* Even if there is more, prevent a loop */
}
} else {
data = FALSE;
}
}
}
if (username && channel) {
/*
* Disjoin sysop channel
*/
/* *** Sysop has terminated chat *** */
sprintf(buf, "%s", (char *) Language(60));
DispMsg(buf);
Syslog('+', "Sysop chat ended");
chat_with_sysop = FALSE;
} else {
Syslog('+', "User chat ended");
}
/*
* Close server connection
*/
sprintf(buf, "CCLO,1,%d;", mypid);
Syslog('-', "> %s", buf);
if (socket_send(buf) == 0) {
strcpy(buf, socket_receive());
Syslog('-', "< %s", buf);
if (strncmp(buf, "100:1,", 6)) {
}
}
sleep(2);
clear();
}