Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

Commit 7fb48f0e authored by deuce's avatar deuce

Initial import of The Online Pub... a chat door.

parent 597fc44f
pwCPP := g++
CC ?= gcc
OS := $(shell uname)
OS := $(shell echo $(OS) | tr "[ A-Z]" "[\-a-z]")
OS := $(shell echo $(OS) | tr -d "/")
CCFLAGS += -g -O2 -I/usr/bbs/sbbs/src/src/odoors -L/usr/bbs/sbbs/doors/libs.$(OS) -I./xpdev
ifeq ($(OS),netbsd)
CCFLAGS += -D__unix__
endif
OBJDIR := obj.$(OS)/
vpath %.c ./xpdev
all : topact.$(OS) top.$(OS) topmaint.$(OS)
$(OBJDIR):
mkdir $(OBJDIR)
$(OBJDIR)filewrap.o: $(OBJDIR) xpdev/filewrap.c xpdev/filewrap.h xpdev/wrapdll.h
$(CC) $(CCFLAGS) -c xpdev/filewrap.c -o $(OBJDIR)filewrap.o
$(OBJDIR)dirwrap.o: $(OBJDIR) xpdev/dirwrap.c xpdev/dirwrap.h xpdev/genwrap.h xpdev/gen_defs.h xpdev/wrapdll.h
$(CC) $(CCFLAGS) -c xpdev/dirwrap.c -o $(OBJDIR)dirwrap.o
$(OBJDIR)genwrap.o: $(OBJDIR) xpdev/genwrap.c xpdev/genwrap.h xpdev/gen_defs.h xpdev/wrapdll.h
$(CC) $(CCFLAGS) -c xpdev/genwrap.c -o $(OBJDIR)genwrap.o
$(OBJDIR)datewrap.o: $(OBJDIR) xpdev/datewrap.c xpdev/datewrap.h xpdev/gen_defs.h xpdev/wrapdll.h
$(CC) $(CCFLAGS) -c xpdev/datewrap.c -o $(OBJDIR)datewrap.o
$(OBJDIR)strwrap.o: $(OBJDIR) xpdev/strwrap.c xpdev/strwrap.h xpdev/gen_defs.h xpdev/wrapdll.h
$(CC) $(CCFLAGS) -c xpdev/strwrap.c -o $(OBJDIR)strwrap.o
$(OBJDIR)conwrap.o: $(OBJDIR) xpdev/conwrap.c xpdev/conwrap.h xpdev/gen_defs.h xpdev/wrapdll.h
$(CC) $(CCFLAGS) -c xpdev/conwrap.c -o $(OBJDIR)conwrap.o
topact.$(OS) : topact.c $(OBJDIR)genwrap.o $(OBJDIR)filewrap.o
$(CC) $(CCFLAGS) topact.c $(OBJDIR)genwrap.o $(OBJDIR)filewrap.o -o topact.$(OS)
topmaint.$(OS) : topmaint.c $(OBJDIR)genwrap.o $(OBJDIR)filewrap.o $(OBJDIR)datewrap.o $(OBJDIR)conwrap.o
$(CC) $(CCFLAGS) topmaint.c $(OBJDIR)genwrap.o $(OBJDIR)filewrap.o $(OBJDIR)datewrap.o $(OBJDIR)conwrap.o -o topmaint.$(OS)
# Implicit C Compile Rule
$(OBJDIR)%.o : %.c
$(CC) $(CCFLAGS) -o $@ -c $<
clean:
rm -rf topact.$(OS) top.$(OS) topmaint.$(OS) $(OBJDIR)
OBJS := $(OBJDIR)actions.o \
$(OBJDIR)bbs.o \
$(OBJDIR)bbssbbs.o \
$(OBJDIR)bio.o \
$(OBJDIR)censor.o \
$(OBJDIR)cfg.o \
$(OBJDIR)change.o \
$(OBJDIR)channels.o \
$(OBJDIR)cmi.o \
$(OBJDIR)help.o \
$(OBJDIR)kernel.o \
$(OBJDIR)lang.o \
$(OBJDIR)main.o \
$(OBJDIR)maint.o \
$(OBJDIR)messages.o \
$(OBJDIR)moderate.o \
$(OBJDIR)nodecfg.o \
$(OBJDIR)nodes.o \
$(OBJDIR)privchat.o \
$(OBJDIR)procinp.o \
$(OBJDIR)profile.o \
$(OBJDIR)screens.o \
$(OBJDIR)strings.o \
$(OBJDIR)sysop.o \
$(OBJDIR)words.o \
$(OBJDIR)bbsmax.o \
$(OBJDIR)bbsra.o \
$(OBJDIR)global.o \
$(OBJDIR)init.o \
$(OBJDIR)output.o \
$(OBJDIR)procmsgs.o \
$(OBJDIR)system.o \
$(OBJDIR)user.o \
$(OBJDIR)filewrap.o \
$(OBJDIR)dirwrap.o \
$(OBJDIR)genwrap.o \
$(OBJDIR)datewrap.o \
$(OBJDIR)strwrap.o \
$(OBJDIR)matchgam.o \
$(OBJDIR)slots.o \
# $(OBJDIR)bbswc.o \ # Experimental
# $(OBJDIR)charchat.o \ # Experimental
# $(OBJDIR)spawn.o \ # *MAY* not be required
top.$(OS) : $(OBJS)
$(CC) $(CCFLAGS) -o $@ $^ -lODoors
This diff is collapsed.
/******************************************************************************
BBS.C Generic BBS functions.
Copyright 1993 - 2000 Paul J. Sidorsky
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2, as
published by the Free Software Foundation.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
This module contains the NODES and PAGE commands, and functions which front-end
the BBS-specific calls.
******************************************************************************/
#include "top.h"
/* bbs_useron() - Displays who is logged on to the BBS. (NODES command.)
Parameters: endpause - TRUE to pause after displaying the list.
Returns: Nothing.
Notes: The code to support the endpause flag has been removed so the
parameter is effectively unused.
*/
void bbs_useron(char endpause)
{
XINT d, count, key, res = 1; /* Counters, keypress holder, result code. */
char nonstop = 0; /* Nonstop mode flag. */
bbsnodedata_typ nodeinf; /* Buffer for BBS data. */
node_idx_typ nodedat; /* Buffer for NODEIDX data. */
/* Set up and display the header. */
// Should be an assertion
if (bbs_call_setexistbits != NULL)
(*bbs_call_setexistbits)(&nodeinf);
bbs_useronhdr(&nodeinf);
check_nodes_used(FALSE);
for (d = 0, count = 0; d < MAXNODES; d++)
{
/* Show a more prompt if 20 nodes have been shown. */
if ((count % 20 == 0) && !nonstop && count > 0) // Use screenlength!
{
nonstop = moreprompt();
if (nonstop == -1)
{
break;
}
}
memset(&nodeinf, 0, sizeof(bbsnodedata_typ) - 2);
memset(&nodedat, 0, sizeof(node_idx_typ));
if (activenodes[d])
{
/* If the node is active in TOP then use the NODEIDX data. This is
done because it is faster and more reliable. */
res = get_node_data(d, &nodedat);
if (!res)
{
fixname(nodeinf.handle, nodedat.handle);
fixname(nodeinf.realname, nodedat.realname);
nodeinf.node = d;
nodeinf.speed = nodedat.speed;
strcpy(nodeinf.location, nodedat.location);
strcpy(nodeinf.statdesc,
top_output(OUT_STRING, getlang("NodeStatus")));
nodeinf.quiet = nodedat.quiet;
nodeinf.gender = nodedat.gender;
nodeinf.hidden = 0;
}
}
else
{
/* Load the data from the BBS's useron file. */
if (bbs_call_loaduseron)
res = (*bbs_call_loaduseron)(d, &nodeinf);
if (res == -2)
{
break;
}
}
/* Display the appropriate information for the node. */
if (!nodeinf.hidden && !res)
{
if (nodeinf.existbits & NEX_NODE)
{
itoa(nodeinf.node, outnum[0], 10);
top_output(OUT_SCREEN, getlang("NodesNodeDisp"), outnum[0]);
}
if ((nodeinf.existbits & NEX_HANDLE) && cfg.usehandles)
{
top_output(OUT_SCREEN, getlang("NodesHandleDisp"),
nodeinf.handle);
}
if ((nodeinf.existbits & NEX_REALNAME) && !cfg.usehandles)
{
top_output(OUT_SCREEN, getlang("NodesRealNameDisp"),
nodeinf.realname);
}
if (nodeinf.existbits & NEX_SPEED)
{
ltoa(nodeinf.speed, outnum[0], 10);
top_output(OUT_SCREEN, getlang("NodesSpeedDisp"), outnum[0]);
}
if (nodeinf.existbits & NEX_LOCATION)
{
top_output(OUT_SCREEN, getlang("NodesLocationDisp"),
nodeinf.location);
}
if (nodeinf.existbits & NEX_STATUS)
{
top_output(OUT_SCREEN, getlang("NodesStatusDisp"),
nodeinf.statdesc);
}
if (nodeinf.existbits & NEX_PAGESTAT)
{
top_output(OUT_SCREEN, getlang("NodesPageStatDisp"),
nodeinf.quiet ? getlang("PageStatNo") :
getlang("PageStatYes"));
} // Also add GENDER and NUMCALLS!
top_output(OUT_SCREEN, getlang("NodesListEndLine"));
count++;
}
}
if (endpause)
{
// Language-enabled press-a-key later.
// top_output(OUT_SCREEN, getlang("NodesListAfterKey"));
}
}
/* bbs_page() - Sends a message from TOP to a user on the BBS (PAGE cmd.)
Parameters: nodenum - Node number to page, or -1 to prompt user.
pagebuf - String containing the page text, or NULL to use the
editor.
Returns: Nothing.
*/
void bbs_page(XINT nodenum, unsigned char *pagebuf)
{
/* Final page buffer, string conversion of node number. */
unsigned char *pagemsg = NULL, pnode[6];
XINT pagenode, pres; /* Final node to page, result code. */
bbsnodedata_typ pnodeinf; /* Buffer for BBS data. */
node_idx_typ pnodedat; /* Buffer for NODEIDX data. */
/* Allocate an edit buffer if no string was passed. */
if (pagebuf == NULL)
{
pagemsg = malloc(1601);
if (!pagemsg)
{
top_output(OUT_SCREEN, getlang("NoMemToPage"));
return;
}
}
if (nodenum < 0)
{
/* Prompt the user for a node number if none was passed. */
do
{ // Need to change this back to the old way...
top_output(OUT_SCREEN, getlang("PageWho"));
od_input_str(pnode, 5, '0', '?');
if (pnode[0] == '?')
{
bbs_useron(FALSE);
top_output(OUT_SCREEN, "@c");
}
}
while(pnode[0] == '?');
pagenode = atoi(pnode);
if (!pnode[0])
{
top_output(OUT_SCREEN, getlang("PageAborted"));
dofree(pagemsg);
return;
}
itoa(pagenode, pnode, 10);
if (pagenode < 1 || pagenode >= cfg.maxnodes)
{
itoa(cfg.maxnodes - 1, outnum[0], 10);
top_output(OUT_SCREEN, getlang("InvalidNode"), outnum[0]);
dofree(pagemsg);
return;
}
}
else
{
pagenode = nodenum;
itoa(nodenum, pnode, 10);
}
pres = 0;
memset(&pnodeinf, 0, sizeof(bbsnodedata_typ) - 2);
memset(&pnodedat, 0, sizeof(node_idx_typ));
if (activenodes[pagenode])
{
/* If the user's in TOP, use the NODEIDX data instead. */
pres = get_node_data(pagenode, &pnodedat);
pnodeinf.quiet = pnodedat.quiet;
}
else
{
pres = 1;
/* Load the user's data from the BBS. */
if (bbs_call_loaduseron)
pres = (*bbs_call_loaduseron)(pagenode, &pnodeinf);
if (pres)
{
pnodeinf.hidden = 1;
}
}
/* Page is aborted if node is hidden or not in use, or if user is in Quiet
mode. */
if (pnodeinf.hidden)
{
top_output(OUT_SCREEN, getlang("NodeNotInUse"), pnode);
dofree(pagemsg);
return;
}
if (pnodeinf.quiet)
{
top_output(OUT_SCREEN, getlang("NodeDND"), pnode);
dofree(pagemsg);
return;
}
if (pagebuf == NULL)
{
/* Call the editor if no page was passed. */
memset(pagemsg, 0, 1601);
(*bbs_call_pageedit)(pagenode, pagemsg); // use retval later
}
else
{
pagemsg = pagebuf;
}
/* Performs the actual paging of the user if that function is available. */
if (bbs_call_page != NULL)
{
if ((*bbs_call_page)(pagenode, pagemsg))
{
top_output(OUT_SCREEN, getlang("Paged"), pnode);
od_log_write(top_output(OUT_STRING, getlang("LogSentPage"),
pnode));
}
}
else
{
top_output(OUT_SCREEN, getlang("CantPage"), pnode);
od_log_write(top_output(OUT_STRING, getlang("LogCantPage"), pnode));
}
// Possible else & case for errorcodes
/* Free the edit buffer if it was used. */
if (pagebuf == NULL)
{
dofree(pagemsg);
}
}
/* bbs_useronhdr() - Shows the header for the NODES command.
Parameters: ndata - Pointer to the BBS node data being used.
Returns: Nothing.
Notes: Only the existbits are used from ndata. The buffer pointed to
by ndata should first be initialized using a call to the function
pointed to by bbs_call_setexistbits.
*/
void bbs_useronhdr(bbsnodedata_typ *ndata)
{
top_output(OUT_SCREEN, getlang("NodesHdrPrefix"));
/* Show only the desired fields. */
if (ndata->existbits & NEX_NODE)
{
top_output(OUT_SCREEN, getlang("NodesNodeHdr"));
}
if ((ndata->existbits & NEX_HANDLE) && cfg.usehandles)
{
top_output(OUT_SCREEN, getlang("NodesHandleHdr"));
}
if ((ndata->existbits & NEX_REALNAME) && !cfg.usehandles)
{
top_output(OUT_SCREEN, getlang("NodesRealNameHdr"));
}
if (ndata->existbits & NEX_SPEED)
{
top_output(OUT_SCREEN, getlang("NodesSpeedHdr"));
}
if (ndata->existbits & NEX_LOCATION)
{
top_output(OUT_SCREEN, getlang("NodesLocationHdr"));
}
if (ndata->existbits & NEX_STATUS)
{
top_output(OUT_SCREEN, getlang("NodesStatusHdr"));
}
if (ndata->existbits & NEX_PAGESTAT)
{
top_output(OUT_SCREEN, getlang("NodesPageStatHdr"));
} // Also add GENDER and NUMCALLS!
top_output(OUT_SCREEN, getlang("NodesHdrSuffix"));
top_output(OUT_SCREEN, getlang("NodesSepPrefix"));
/* Show separators for the desired fields. */
if (ndata->existbits & NEX_NODE)
{
top_output(OUT_SCREEN, getlang("NodesNodeSep"));
}
if ((ndata->existbits & NEX_HANDLE) && cfg.usehandles)
{
top_output(OUT_SCREEN, getlang("NodesHandleSep"));
}
if ((ndata->existbits & NEX_REALNAME) && !cfg.usehandles)
{
top_output(OUT_SCREEN, getlang("NodesRealNameSep"));
}
if (ndata->existbits & NEX_SPEED)
{
top_output(OUT_SCREEN, getlang("NodesSpeedSep"));
}
if (ndata->existbits & NEX_LOCATION)
{
top_output(OUT_SCREEN, getlang("NodesLocationSep"));
}
if (ndata->existbits & NEX_STATUS)
{
top_output(OUT_SCREEN, getlang("NodesStatusSep"));
}
if (ndata->existbits & NEX_PAGESTAT)
{
top_output(OUT_SCREEN, getlang("NodesPageStatSep"));
} // Also add GENDER and NUMCALLS!
top_output(OUT_SCREEN, getlang("NodesSepSuffix"));
}
/******************************************************************************
BBSMAX.C Implements Maximus-specific BBS functions.
Copyright 1993 - 2000 Paul J. Sidorsky
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2, as
published by the Free Software Foundation.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
The module contains all of the functions for interfacing with Maximus v2.xx and
v3.xx, excluding Maximus for OS/2 v3.0x.
******************************************************************************/
#include "top.h"
/* Blinking test used when displaying MECCA strings. */
#define blinking (blink ? 0x80 : 0x00)
/* max_init() - Initialize pointers to Maximus functions.
Paremeters: None.
Returns: Nothing.
*/
void max_init(void)
{
bbs_call_loaduseron = max_loadipcstatus;
bbs_call_saveuseron = max_saveipcstatus;
bbs_call_processmsgs = max_processipcmsgs;
bbs_call_page = max_page;
bbs_call_setexistbits = max_setexistbits;
bbs_call_login = max_login;
bbs_call_logout = max_logout;
bbs_call_openfiles = max_openfiles;
bbs_call_updateopenfiles = max_openfiles;
bbs_call_pageedit = max_shortpageeditor;
}
/* max_loadipcstatus() - Loads a node status from an IPC file.
Parameters: nodenum - Node number to load the data for.
userdata - Pointer to generic BBS data structure to fill.
Returns: TRUE if an error occurred, FALSE if successful.
*/
char max_loadipcstatus(XINT nodenum, bbsnodedata_typ *userdata)
{
char risnam[MAX_PATH]; /* IPC file name. */
XINT res; /* Result code. */
struct _cstat statbuf; /* Maximus node status buffer. */
/* Open the IPC file and read the status information. */
sprintf(risnam, "%sipc%02X.bbs", cfg.bbsmultipath, nodenum);
ipcoutfil = sh_open(risnam, O_RDONLY | O_BINARY, SH_DENYNO, S_IREAD | S_IWRITE);
if (ipcoutfil == -1)
{
return 1;
}
lseek(ipcoutfil, 0, SEEK_SET);
rec_locking(REC_LOCK, ipcoutfil, 0, sizeof(struct _cstat));
res = read(ipcoutfil, &statbuf, sizeof(struct _cstat));
rec_locking(REC_UNLOCK, ipcoutfil, 0, sizeof(struct _cstat));
if (res == -1)
{
close(ipcoutfil);
return 1;
}
close(ipcoutfil);
/* Copy the status information to the generic structure. */
userdata->quiet = !statbuf.avail;
fixname(userdata->realname, statbuf.username);
fixname(userdata->handle, statbuf.username);
strcpy(userdata->statdesc, statbuf.status);
userdata->node = nodenum;
return 0;
}
/* max_saveipcstatus() - Saves a node status to an IPC file.
Parameters: nodenum - Node number to save the data for.
userdata - Pointer to generic BBS data structure to use.
Returns: TRUE if an error occurred, FALSE if successful.
*/
char max_saveipcstatus(XINT nodenum, bbsnodedata_typ *userdata)
{
char winam[MAX_PATH]; /* IPC file name. */
XINT res; /* Result code. */
struct _cstat nodeinf; /* Maximus node status buffer. */
char sist = 1; /* Flag indicating that there are messages in the IPC file. */
/* Transfer the data from the generic BBS structure. */
nodeinf.avail = !userdata->quiet;
strcpy(nodeinf.username,
cfg.usehandles ? userdata->handle : userdata->realname);
strcpy(nodeinf.status, userdata->statdesc);
/* Open the file, creating it if it doesn't exist. */
sprintf(winam, "%sipc%02X.bbs", cfg.bbsmultipath, nodenum);
ipcoutfil = sh_open(winam, O_WRONLY | O_CREAT, SH_DENYNO, S_IREAD | S_IWRITE);
if (ipcoutfil == -1)
{
return 1;
}
/* If TOP created the IPC file, initialize the message data. */
if (filelength(ipcoutfil) < sizeof(struct _cstat))
{
nodeinf.msgs_waiting = 0;
nodeinf.next_msgofs = sizeof(struct _cstat);
nodeinf.new_msgofs = sizeof(struct _cstat);
chsize(ipcoutfil, sizeof(struct _cstat));
sist = 0;
}
/* Save the node status information. */
lseek(ipcoutfil, 0, SEEK_SET);
rec_locking(REC_LOCK, ipcoutfil, 0, sizeof(struct _cstat));
/* If sist is 1 then there may be messages in the file that have not been
sent, so the message data is not disturbed. */
res = write(ipcoutfil, &nodeinf,
sist ? (sizeof(struct _cstat) - 10) : sizeof(struct _cstat));
rec_locking(REC_UNLOCK, ipcoutfil, 0, sizeof(struct _cstat));
if (res == -1)
{
close(ipcoutfil);
return 1;
}
close(ipcoutfil);
return 0;