home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.wwiv.com
/
ftp.wwiv.com.zip
/
ftp.wwiv.com
/
pub
/
BBS
/
TBZCDR11.ZIP
/
TBZCDRWY.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-25
|
10KB
|
414 lines
/*
TBZCDRWY.C - A TriBBS-specific front door for the Z-Chat multinode, chat
door, using TriDoor from Mark Goodwin.
Copyright (c) 1995 by Marc Brooks
Compile as follows:
Borland C++ : bcc -ml tbzcdrwy.c bctdoor.lib
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <dos.h>
#include <fcntl.h>
#include <share.h>
#include <sys\stat.h>
#include <io.h>
#include "tdoor.h"
#include "triwho.h"
#define TRUE 1
#define FALSE 0
#define DIM(x) (sizeof(x) / sizeof(x[0]))
#define MAX_NAME 30 /* determined by length of WHOSON data file */
#define MAX_NODES 30 /* for this compilation */
#define MAX_PATH 128
#define MAX_LINE 80
#define NOT_LOGGED_ON -1
#define TBZCVER "TriBBS Z-Chat Doorway 1.1"
const char *ChatStatStrings[] = {
"Available",
"NOT Available",
"Transfering a file",
"Entering a message",
"In another door",
"Group chatting",
"Waiting for node",
"Chatting with node"
};
char common_path[MAX_PATH + 1];
int maximum_nodes;
int my_node;
struct {
char who[MAX_NAME + 1];
int where;
} node_info[MAX_NODES];
typedef enum { INITIALIZE = 0,
GET_NODE = 1,
START_CHAT = 2,
DIE = 3 } states;
states status;
typedef enum { READ_BINARY = 0, APPEND_TEXT = 1, READ_WRITE_BINARY = 2 } mode_flag;
static int open_modes[] = { O_RDONLY | O_BINARY, O_WRONLY | O_APPEND | O_TEXT, O_RDWR | O_BINARY };
static char* fopen_modes[] = { "rb", "at", "r+b" };
static void GetOthers(void);
static void GetConfigLine(FILE *cfg, int max, char *line, char *expected);
static int GetNode(void);
static int JustBack(void);
static FILE *ReadWho(int node, TriWho *who);
static void SetupStuff(char *cfg_file);
static void TrimTail(char* str);
static void EnterChat(int node);
static FILE *ShareOpen(char* name, mode_flag open_mode, int share_mode);
extern unsigned _stklen = 8192;
int main(int ac, char *av[])
{
if (ac < 2)
{
printf("%s\n", TBZCVER);
printf("Copyright (c) 1995, Phydeaux Software, Inc.\n\n");
printf("Thanks to: Mark Goodwin for TriDoor\n");
printf("You must supply a configuration file name.\n");
exit(1);
}
TDInitialize(ac, av);
strcpy(TDDoorName, TBZCVER);
SetupStuff(av[1]);
if (status != DIE)
{
if (!JustBack())
{
GetOthers();
if (GetNode())
{
TDSetColor(WHITE, BLACK);
TDPrintf("\nLoading the Z-Chat program.\n");
return (0);
}
}
}
TDSetColor(CYAN, BLACK);
TDPrintf("\nReturning you to the BBS.\n");
sleep(1);
return (status == DIE ? 2 : 1);
}
static void SetupStuff(char *cfg_file)
{
FILE *cfg;
int i;
char line[MAX_LINE + 1];
status = INITIALIZE;
for (i = 0; i < MAX_NODES; i++)
{
node_info[i].who[0] = '\0';
node_info[i].where = NOT_LOGGED_ON;
}
cfg = ShareOpen(cfg_file, READ_BINARY, SH_DENYNO);
if (cfg != NULL)
{
GetConfigLine(cfg, MAX_LINE, line, "BBS Type"); // get the bbs type
GetConfigLine(cfg, MAX_LINE, line, "Path to door file"); // skip the path to the door data files
GetConfigLine(cfg, MAX_LINE, line, "BBS Name"); // skip the bbs name
GetConfigLine(cfg, MAX_LINE, line, "Sysop Name"); // skip the sysop's name
GetConfigLine(cfg, MAX_LINE, line, "Locked baud rate"); // skip the locked baud rate
GetConfigLine(cfg, MAX_PATH, common_path, "Node one path"); // get the node one path
GetConfigLine(cfg, MAX_LINE, line, "Maximum nodes"); // get the maximum number of nodes
maximum_nodes = atoi(line);
if ((maximum_nodes < 1) || (maximum_nodes > MAX_NODES))
{
status = DIE;
TDSetColor(RED, BLACK);
TDPrintf("HEY! Maximum nodes must be between 1 and %d!\n\n", MAX_NODES);
}
my_node = TDNode;
if ((my_node < 1) || (my_node > maximum_nodes))
{
status = DIE;
TDSetColor(RED, BLACK);
TDPrintf("HEY! The node number (%d) is invalid, must be 1 to %d (%d).\n\n",
my_node, maximum_nodes, MAX_NODES);
}
fclose(cfg);
}
else {
status = DIE;
TDSetColor(RED, BLACK);
TDPrintf("HEY! Can't find my configuration file (%s)!\n\n", cfg_file);
}
}
static int JustBack(void)
{
FILE *fp;
TriWho who;
int retval = 0;
fp = ReadWho(my_node, &who);
if (fp != NULL)
{
if ((who.chat_status == TRI_IN_GROUP_CHAT) ||
(who.chat_status == TRI_WAITING_FOR_NODE) ||
(who.chat_status == TRI_IN_NODE_CHAT))
{
who.chat_status = TRI_IN_DOOR;
fseek(fp, 0L, SEEK_SET);
fwrite(&who, sizeof(who), 1, fp);
retval = 1;
}
fclose(fp);
}
return retval;
}
static void GetOthers(void)
{
FILE *fp;
int i;
TriWho who;
for (i = 0; i < maximum_nodes; i++)
{
node_info[i].who[0] = '\0';
node_info[i].where = NOT_LOGGED_ON;
fp = ReadWho(i + 1, &who);
if (fp != NULL)
{
strncpy(node_info[i].who, who.name, 31);
node_info[i].where = who.chat_status;
fclose(fp);
}
}
}
static int GetNode(void)
{
int i;
char line[MAX_LINE];
while (1)
{
TDSetColor(LIGHTGREEN, BLACK);
TDPuts("Node Name");
for (i = 0; i < MAX_NAME - 4; i++)
TDPutch(' ');
TDPuts(" Chat Status\n");
TDPuts("---- ");
for (i = 0; i < MAX_NAME; i++)
TDPutch('-');
TDPuts(" -------------------\n");
for (i = 0; i < maximum_nodes; i++)
{
TDSetColor(LIGHTCYAN, BLACK);
TDPrintf(" %2d ", i + 1);
if (node_info[i].where != NOT_LOGGED_ON)
{
TDSetColor(LIGHTGREEN, BLACK);
TDPrintf(" %-*.*s", MAX_NAME, MAX_NAME, node_info[i].who);
TDSetColor(WHITE, BLACK);
TDPrintf(" %s", (i + 1 == my_node) ?
"Here!" :
ChatStatStrings[node_info[i].where]);
}
else TDPuts(" No one logged into this node");
TDPutch('\n');
}
TDSetColor(LIGHTGREEN, BLACK);
TDPrintf("\nSelect Node number (1-%d), <G> for group chat, <ENTER> to quit: ",
maximum_nodes);
TDSetColor(WHITE, BLACK);
TDGets(line, MAX_LINE);
if (line[0] == '\0')
return 0;
if (toupper(line[0]) == 'G')
{
EnterChat(0);
return 1;
}
i = atoi(line);
if ((i < 1) && (i > maximum_nodes))
{
TDSetColor(BLACK, RED);
TDPrintf("\nYou must enter either a node number or G!\n");
continue;
}
if (i == my_node)
{
TDSetColor(BLACK, RED);
TDPrintf("\nYou can't chat with yourself!\n");
continue;
}
if (node_info[i - 1].where == TRI_UNAVAILABLE)
{
TDSetColor(BLACK, RED);
TDPrintf("\n%s does not want to chat right now!\n", node_info[i - 1].who);
continue;
}
if (node_info[i - 1].where == TRI_AVAILABLE)
{
TDSetColor(LIGHTCYAN, BLACK);
TDPrintf("\n%s will be notified you want to chat, be patient...\n",
node_info[i - 1].who);
}
EnterChat(i);
return 1;
}
}
static void GetConfigLine(FILE *cfg, int max, char *line, char *expected)
{
if (fgets(line, max, cfg) == NULL)
{
status = DIE;
TDSetColor(RED, BLACK);
TDPrintf("You seem to be missing something in the config file.\n");
TDPrintf("I was expecting %s, and the line was missing.\n", expected);
}
else TrimTail(line);
}
static void TrimTail(char *str)
{
register int i = strlen(str);
register char *end = &str[i - 1];
while ((i > 0) && ((*end == '\n') || (*end == '\r') ||
(*end == ' ') || (*end == '\t')))
{
i--;
*end-- = '\0';
}
}
static void EnterChat(int node)
{
FILE *fp;
int i;
TriWho who;
char who_file[MAX_PATH + 1];
fp = ReadWho(my_node, &who);
if (fp != NULL)
{
if (node != 0)
who.chat_status = TRI_IN_NODE_CHAT;
else who.chat_status = TRI_IN_GROUP_CHAT;
who.other_node = node;
fseek(fp, 0L, SEEK_SET);
fwrite(&who, sizeof(who), 1, fp);
fclose(fp);
}
/* If the node is 0 (which is group chat) then we send the message to */
/* all other nodes. */
for (i = 0; i < maximum_nodes; i++)
{
if (i + 1 == my_node)
continue; /* don't tell me! */
/* Don't nag that are not available for chat */
if (node_info[i].where != TRI_AVAILABLE)
continue;
if ((node == i + 1) || (node == 0))
{
sprintf(who_file, "%s\\MWORK\\PAGE.%03d", common_path, i + 1);
fp = ShareOpen(who_file, APPEND_TEXT, SH_DENYNO);
if (fp != NULL)
{
fprintf(fp, "%s on node %d %s chat!\n",
node_info[my_node - 1].who,
my_node,
node ? "wants to" : "just entered");
fclose(fp);
}
}
}
}
static FILE *ReadWho(int node, TriWho *who)
{
FILE *fp;
char who_file[MAX_PATH + 1];
sprintf(who_file, "%s\\MWORK\\WHOSON.%d", common_path, node);
fp = ShareOpen(who_file, READ_WRITE_BINARY, SH_DENYNO);
if (fp != NULL)
{
if (fread(who, sizeof(*who), 1, fp) != 1)
{
fclose(fp);
fp = NULL;
}
}
return fp;
}
static FILE *ShareOpen(char* name, mode_flag open_mode, int share_mode)
{
int fd;
FILE *fp = NULL;
fd = sopen(name, open_modes[open_mode], share_mode, S_IREAD | S_IWRITE);
if (fd != -1)
{
fp = fdopen(fd, fopen_modes[open_mode]);
if (fp == NULL)
close(fd);
}
return fp;
}