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

417 lines
10 KiB
C
Raw Normal View History

2001-08-17 05:46:24 +00:00
/*****************************************************************************
*
* $Id$
2001-08-17 05:46:24 +00:00
* Purpose ...............: Sysop to user chat utility
*
*****************************************************************************
2006-02-05 13:21:34 +00:00
* Copyright (C) 1997-2006
2001-08-17 05:46:24 +00:00
*
2002-01-07 19:16:03 +00:00
* Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10
2001-08-17 05:46:24 +00:00
* 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
2003-08-15 20:05:34 +00:00
* Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
2001-08-17 05:46:24 +00:00
*****************************************************************************/
2002-06-30 12:48:44 +00:00
#include "../config.h"
2004-02-21 17:22:00 +00:00
#include "../lib/mbselib.h"
2001-08-17 05:46:24 +00:00
#include "../lib/mbse.h"
2002-01-07 19:16:03 +00:00
#include "../lib/users.h"
2001-08-17 05:46:24 +00:00
#include "chat.h"
#include "funcs.h"
#include "input.h"
2001-08-17 05:46:24 +00:00
#include "language.h"
#include "misc.h"
#include "whoson.h"
#include "term.h"
2004-11-03 20:48:45 +00:00
#include "ttyio.h"
2004-11-12 21:25:59 +00:00
#include "timeout.h"
2001-08-17 05:46:24 +00:00
#define RBUFLEN 81
2003-04-01 21:41:36 +00:00
int chat_with_sysop = FALSE; /* Global sysop chat flag */
int chatting = FALSE; /* Global chatting flag */
char rbuf[50][RBUFLEN]; /* Chat receive buffer */ /* FIXME: must be a dynamic buffer */
2003-04-01 21:41:36 +00:00
int rpointer = 0; /* Chat receive pointer */
int rsize = 5; /* Chat receive size */
extern pid_t mypid;
2005-10-07 20:42:35 +00:00
extern int cols;
extern int rows;
2001-08-17 05:46:24 +00:00
2003-04-02 21:36:47 +00:00
void Showline(int, int, char *);
2003-04-01 21:41:36 +00:00
void DispMsg(char *);
void clrtoeol(void);
unsigned char testkey(int, int);
2001-08-17 05:46:24 +00:00
2003-04-01 21:41:36 +00:00
unsigned char testkey(int y, int x)
2001-08-17 05:46:24 +00:00
{
2003-04-01 21:41:36 +00:00
int rc;
unsigned char ch = 0;
Nopper();
locate(y, x);
rc = Waitchar(&ch, 50);
if (rc == 1) {
if (ch == KEY_ESCAPE)
rc = Escapechar(&ch);
}
if (rc == 1)
return ch;
else
return '\0';
}
2001-08-17 05:46:24 +00:00
2003-04-02 21:36:47 +00:00
/*
* Colorize the chat window
*/
void Showline(int y, int x, char *msg)
{
2006-02-05 13:21:34 +00:00
int i, done = FALSE;
2003-04-02 21:36:47 +00:00
if (strlen(msg)) {
if (msg[0] == '<') {
locate(y, x);
colour(LIGHTCYAN, BLACK);
2004-11-03 20:48:45 +00:00
PUTCHAR('<');
2003-04-03 20:51:19 +00:00
colour(LIGHTBLUE, BLACK);
2003-04-02 21:36:47 +00:00
for (i = 1; i < strlen(msg); i++) {
2006-02-05 13:21:34 +00:00
if ((msg[i] == '>') && (! done)) {
2003-04-02 21:36:47 +00:00
colour(LIGHTCYAN, BLACK);
2004-11-03 20:48:45 +00:00
PUTCHAR(msg[i]);
2003-04-02 21:36:47 +00:00
colour(CYAN, BLACK);
2006-02-05 13:21:34 +00:00
done = TRUE;
2003-04-02 21:36:47 +00:00
} else {
2004-11-03 20:48:45 +00:00
PUTCHAR(msg[i]);
2003-04-02 21:36:47 +00:00
}
}
} else if (msg[0] == '*') {
2006-02-05 13:21:34 +00:00
if (msg[1] == '*') {
if (msg[2] == '*')
mbse_colour(YELLOW, BLACK);
else
colour(LIGHTRED, BLACK);
} else {
colour(LIGHTMAGENTA, BLACK);
}
mvprintw(y, x, msg);
2003-04-02 21:36:47 +00:00
} else {
2003-04-03 20:51:19 +00:00
colour(GREEN, BLACK);
2003-04-02 21:36:47 +00:00
mvprintw(y, x, msg);
}
}
}
2003-04-01 21:41:36 +00:00
/*
* Display received chat message in the chat window.
*/
void DispMsg(char *msg)
{
int i;
2001-08-17 05:46:24 +00:00
2006-02-05 13:21:34 +00:00
/*
* Beep on minor system messages
*/
if ((msg[0] == '*') && (msg[1] != '*'))
putchar('\007');
strncpy(rbuf[rpointer], msg, RBUFLEN);
2003-04-02 21:36:47 +00:00
Showline(2 + rpointer, 1, rbuf[rpointer]);
2003-04-01 21:41:36 +00:00
if (rpointer == rsize) {
/*
* Scroll buffer
*/
for (i = 0; i <= rsize; i++) {
locate(i + 2, 1);
clrtoeol();
snprintf(rbuf[i], RBUFLEN, "%s", rbuf[i+1]);
2003-04-02 21:36:47 +00:00
Showline(i + 2, 1, rbuf[i]);
2001-08-17 05:46:24 +00:00
}
2003-04-01 21:41:36 +00:00
} else {
rpointer++;
}
}
/*
* Clear to End Of Line
*/
void clrtoeol(void)
{
2004-11-03 20:48:45 +00:00
PUTSTR((char *)ANSI_CLREOL);
2003-04-01 21:41:36 +00:00
}
/*
* 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)
{
2003-04-02 21:36:47 +00:00
int curpos = 0, stop = FALSE, data, rc;
2003-04-01 21:41:36 +00:00
unsigned char ch;
char sbuf[81], resp[128], *name, *mname;
2003-04-01 21:41:36 +00:00
static char buf[200];
2001-08-17 05:46:24 +00:00
2003-10-11 21:22:16 +00:00
WhosDoingWhat(SYSOPCHAT, NULL);
2003-04-01 21:41:36 +00:00
clear();
2005-10-07 20:42:35 +00:00
rsize = rows - 5;
2003-04-01 21:41:36 +00:00
rpointer = 0;
if (SYSOP == TRUE) {
/*
* Forbid the sysop to chat, the sysop MUST use mbmon.
*/
Syslog('+', "The Sysop attempted to chat");
2005-09-02 20:39:54 +00:00
pout(LIGHTRED, BLACK, (char *) Language(29));
Enter(1);
Pause();
return;
}
2003-04-01 21:41:36 +00:00
if (username && channel) {
colour(LIGHTGREEN, BLACK);
2004-11-03 20:48:45 +00:00
PUTCHAR('\007');
2003-04-01 21:41:36 +00:00
/* *** Sysop is starting chat *** */
2004-11-03 20:48:45 +00:00
pout(LIGHTGREEN, BLACK, (char *) Language(59));
Enter(1);
2003-04-01 21:41:36 +00:00
sleep(1);
2004-11-03 20:48:45 +00:00
PUTCHAR('\007');
2003-04-01 21:41:36 +00:00
sleep(1);
2004-11-03 20:48:45 +00:00
PUTCHAR('\007');
2003-04-01 21:41:36 +00:00
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();
2005-10-07 20:42:35 +00:00
snprintf(buf, 200, "%-*s", cols -1, " MBSE BBS Chat Server");
2004-11-03 20:48:45 +00:00
mvprintw(1, 1, buf);
2003-04-01 21:41:36 +00:00
mname = xstrcpy(clencode(exitinfo.sUserName));
name = xstrcpy(clencode(exitinfo.Name));
snprintf(buf, 200, "CCON,4,%d,%s,%s,0;", mypid, mname, name);
free(mname);
free(name);
2006-02-05 13:21:34 +00:00
// Syslog('c', "> %s", buf);
2003-04-01 21:41:36 +00:00
if (socket_send(buf) == 0) {
2003-04-03 20:51:19 +00:00
strncpy(buf, socket_receive(), sizeof(buf)-1);
2006-02-05 13:21:34 +00:00
// Syslog('c', "< %s", buf);
if (strncmp(buf, "200:1,", 6) == 0) {
Syslog('!', "Chatsever is not available");
2003-04-01 21:41:36 +00:00
colour(LIGHTRED, BLACK);
2005-09-02 20:39:54 +00:00
mvprintw(4, 1, (char *) Language(30));
Enter(2);
2003-04-01 21:41:36 +00:00
Pause();
chat_with_sysop = FALSE;
2003-04-02 21:36:47 +00:00
return;
2003-04-01 21:41:36 +00:00
}
}
2005-10-07 20:42:35 +00:00
locate(rows - 2, 1);
2003-04-01 21:41:36 +00:00
colour(WHITE, BLUE);
clrtoeol();
2005-10-07 20:42:35 +00:00
snprintf(buf, 200, "%-*s", cols -1, " Chat, type \"/EXIT\" to exit or \"/HELP\" for help");
mvprintw(rows - 2, 1, buf);
2003-04-01 21:41:36 +00:00
colour(LIGHTGRAY, BLACK);
2005-10-07 20:42:35 +00:00
mvprintw(rows - 1, 1, ">");
2003-04-01 21:41:36 +00:00
memset(&sbuf, 0, sizeof(sbuf));
memset(&rbuf, 0, sizeof(rbuf));
2003-04-02 21:36:47 +00:00
/*
* If username and channelname are given, send the /nick and /join
* commands to the chatserver.
*/
if (username && channel) {
snprintf(buf, 200, "CPUT:2,%d,/nick %s;", mypid, clencode(username));
2003-04-02 21:36:47 +00:00
if (socket_send(buf) == 0)
strcpy(buf, socket_receive());
snprintf(buf, 200, "CPUT:2,%d,/join %s;", mypid, clencode(channel));
2003-04-02 21:36:47 +00:00
if (socket_send(buf) == 0)
strcpy(buf, socket_receive());
}
2006-02-05 13:21:34 +00:00
// Syslog('c', "Start loop");
2003-04-01 21:41:36 +00:00
chatting = TRUE;
while (stop == FALSE) {
2001-08-17 05:46:24 +00:00
/*
2003-04-01 21:41:36 +00:00
* Check for new message, loop fast until no more data available.
2001-08-17 05:46:24 +00:00
*/
2003-04-01 21:41:36 +00:00
data = TRUE;
while (data) {
2005-08-29 12:50:02 +00:00
snprintf(buf, 200, "CGET:1,%d;", mypid);
2003-04-01 21:41:36 +00:00
if (socket_send(buf) == 0) {
2003-04-03 20:51:19 +00:00
strncpy(buf, socket_receive(), sizeof(buf)-1);
2003-04-02 21:36:47 +00:00
if (strncmp(buf, "100:2,", 6) == 0) {
2006-02-05 13:21:34 +00:00
// Syslog('c', "> CGET:1,%d;", mypid);
// Syslog('c', "< %s", buf);
2003-04-01 21:41:36 +00:00
strncpy(resp, strtok(buf, ":"), 10); /* Should be 100 */
2003-04-02 21:36:47 +00:00
strncpy(resp, strtok(NULL, ","), 5); /* Should be 2 */
strncpy(resp, strtok(NULL, ","), 5); /* 1= fatal, chat ended */
rc = atoi(resp);
2003-04-03 20:51:19 +00:00
memset(&resp, 0, sizeof(resp));
strncpy(resp, cldecode(strtok(NULL, ";")), 80); /* The message */
2003-04-01 21:41:36 +00:00
DispMsg(resp);
2003-04-02 21:36:47 +00:00
if (rc == 1) {
Syslog('+', "Chat server error: %s", resp);
stop = TRUE;
data = FALSE;
}
2003-04-01 21:41:36 +00:00
} else {
data = FALSE;
2001-08-17 05:46:24 +00:00
}
2003-04-01 21:41:36 +00:00
}
}
2001-08-17 05:46:24 +00:00
2003-04-02 21:36:47 +00:00
if (stop)
break;
2003-04-01 21:41:36 +00:00
/*
2005-04-03 21:26:31 +00:00
* Check for a pressed key, if so then process it.
* Allow hi-ascii for multi-language.
2003-04-01 21:41:36 +00:00
*/
2005-10-07 20:42:35 +00:00
ch = testkey(rows -1, curpos + 2);
2005-04-06 20:50:00 +00:00
if ((ch == KEY_BACKSPACE) || (ch == KEY_RUBOUT) || (ch == KEY_DEL)) {
2004-11-12 21:25:59 +00:00
alarm_on();
2003-04-01 21:41:36 +00:00
if (curpos) {
curpos--;
sbuf[curpos] = '\0';
2004-11-03 20:48:45 +00:00
BackErase();
2003-04-01 21:41:36 +00:00
} else {
2004-11-03 20:48:45 +00:00
PUTCHAR(7);
2003-04-01 21:41:36 +00:00
}
2005-04-06 20:50:00 +00:00
/* if KEY_DEL isprint, do no output again */
} else if (isprint(ch) || traduce(&ch)) {
alarm_on();
if (curpos < 77) {
PUTCHAR(ch);
sbuf[curpos] = ch;
curpos++;
} else {
PUTCHAR(7);
}
2003-04-01 21:41:36 +00:00
} else if ((ch == '\r') && curpos) {
2004-11-12 21:25:59 +00:00
alarm_on();
snprintf(buf, 200, "CPUT:2,%d,%s;", mypid, clencode(sbuf));
2006-02-05 13:21:34 +00:00
// Syslog('c', "> %s", clencode(buf));
2003-04-01 21:41:36 +00:00
if (socket_send(buf) == 0) {
strcpy(buf, socket_receive());
2006-02-05 13:21:34 +00:00
// Syslog('c', "< %s", buf);
2003-04-02 21:36:47 +00:00
if (strncmp(buf, "100:2,", 6) == 0) {
2003-04-01 21:41:36 +00:00
strncpy(resp, strtok(buf, ":"), 10); /* Should be 100 */
2003-04-02 21:36:47 +00:00
strncpy(resp, strtok(NULL, ","), 5); /* Should be 2 */
strncpy(resp, strtok(NULL, ","), 5); /* 1= fatal, chat ended */
rc = atoi(resp);
strncpy(resp, cldecode(strtok(NULL, ";")), 80); /* The message */
2003-04-01 21:41:36 +00:00
DispMsg(resp);
2003-04-02 21:36:47 +00:00
if (rc == 1) {
Syslog('+', "Chat server error: %s", resp);
stop = TRUE;
}
2001-08-17 05:46:24 +00:00
}
2003-04-01 21:41:36 +00:00
}
curpos = 0;
memset(&sbuf, 0, sizeof(sbuf));
2005-10-07 20:42:35 +00:00
locate(rows - 1, 2);
2003-04-01 21:41:36 +00:00
clrtoeol();
2005-10-07 20:42:35 +00:00
mvprintw(rows - 1, 1, ">");
2001-08-17 05:46:24 +00:00
}
2003-04-01 21:41:36 +00:00
}
chatting = FALSE;
2001-08-17 05:46:24 +00:00
2003-04-01 21:41:36 +00:00
/*
* Before sending the close command, purge all outstanding messages.
*/
data = TRUE;
while (data) {
2005-08-29 12:50:02 +00:00
snprintf(buf, 200, "CGET:1,%d;", mypid);
2003-04-01 21:41:36 +00:00
if (socket_send(buf) == 0) {
2003-04-03 20:51:19 +00:00
strncpy(buf, socket_receive(), sizeof(buf)-1);
2003-04-02 21:36:47 +00:00
if (strncmp(buf, "100:2,", 6) == 0) {
2006-02-05 13:21:34 +00:00
// Syslog('c', "> CGET:1,%d;", mypid);
// Syslog('c', "< %s", buf);
2003-04-01 21:41:36 +00:00
strncpy(resp, strtok(buf, ":"), 10); /* Should be 100 */
2003-04-02 21:36:47 +00:00
strncpy(resp, strtok(NULL, ","), 5); /* Should be 2 */
strncpy(resp, strtok(NULL, ","), 5); /* 1= fatal error */
rc = atoi(resp);
2003-04-03 20:51:19 +00:00
memset(&resp, 0, sizeof(resp));
strncpy(resp, cldecode(strtok(NULL, ";")), 80); /* The message */
2003-04-01 21:41:36 +00:00
DispMsg(resp);
2003-04-02 21:36:47 +00:00
if (rc == 1) {
Syslog('+', "Chat server error: %s", resp);
data = FALSE; /* Even if there is more, prevent a loop */
}
2003-04-01 21:41:36 +00:00
} else {
data = FALSE;
}
}
}
if (username && channel) {
/*
* Disjoin sysop channel
*/
/* *** Sysop has terminated chat *** */
2005-08-29 12:50:02 +00:00
snprintf(buf, 200, "%s", (char *) Language(60));
2003-04-01 21:41:36 +00:00
DispMsg(buf);
Syslog('+', "Sysop chat ended");
chat_with_sysop = FALSE;
} else {
Syslog('+', "User chat ended");
}
/*
* Close server connection
*/
2005-08-29 12:50:02 +00:00
snprintf(buf, 200, "CCLO,1,%d;", mypid);
2006-02-05 13:21:34 +00:00
// Syslog('c', "> %s", buf);
2003-04-01 21:41:36 +00:00
if (socket_send(buf) == 0) {
strcpy(buf, socket_receive());
2006-02-05 13:21:34 +00:00
// Syslog('c', "< %s", buf);
2003-04-01 21:41:36 +00:00
}
sleep(2);
clear();
2001-08-17 05:46:24 +00:00
}