home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Unsorted BBS Collection
/
thegreatunsorted.tar
/
thegreatunsorted
/
programming
/
asm_programming
/
MJRDEVEL.ARC
/
MJRTLC.C
< prev
next >
Wrap
Text File
|
1989-03-18
|
28KB
|
834 lines
/***************************************************************************
* *
* MJRTLC.C *
* *
* Copyright (C) 1987-1989 GALACTICOMM, Inc. All Rights Reserved. *
* *
* This is the Major BBS default teleconference handler. *
* *
* - T. Stryker 6/29/86 *
* *
***************************************************************************/
#include "stdio.h"
#include "majorbbs.h"
#include "usracc.h"
#include "mjrtlc.h"
#include "portable.h"
int initlc(),telecn(),dfsthn(),tlchup(),clstlc();
#define TLCSTT 01 /* teleconferencing state */
struct module module01={ /* module interface block */
'*', /* main menu select character (config'able) */
"", /* description for main menu (config'able) */
initlc, /* system initialization routine */
NULL, /* user logon supplemental routine */
telecn, /* input routine if selected */
dfsthn, /* status-input routine if selected */
tlchup, /* hangup (lost carrier) routine */
NULL, /* midnight cleanup routine */
NULL, /* delete-account routine */
clstlc /* finish-up (sys shutdown) routine */
};
#define TPCSIZ 41 /* max size of teleconf channel topic */
static
FILE *tlcmb; /* teleconf named-message file block pointer */
static
struct tlc { /* teleconference per-user volatile data */
int flags; /* telecon user "flag" bits */
long sqlflg[2]; /* "squelch" flags by modem number */
int paged; /* intervals-since-last-paged counter */
int blinkc; /* intervals-since-paged-Sysop counter */
int swchan; /* # of times switched chans in interval */
unsigned channel; /* teleconference channel number in use */
unsigned modchn; /* channel moderated by telecon user */
char topic[TPCSIZ]; /* channel topic as set by moderator */
int inpcnt; /* input message counter for freeloaders */
int reqcha; /* intervals-since-last-chat-request ctr. */
int chatch; /* channel of other user being chatted with*/
int retstt; /* return state number when XTOOTH */
int retsub; /* return sub-state number when XTOOTH */
} *tlclst, /* one to a customer (dynamic array) */
*tlcptr,*tptr; /* handy pointers for speed */
/* definition of telecon user bit "flags" */
#define NOPAGE 1 /* user page-flag set to "off" */
#define SHWCHN 2 /* user's channel is displayed in scan */
#define SQUCHD 4 /* this guy has been "squelched" by modera */
#define LUISSU 8 /* list or unlist command has been issued */
#define JUSTEX 16 /* user "just exited" during current intvl */
#define OKPAGE 32 /* user doesn't mind being paged to death */
#define XTOOTH 64 /* exit to "caller" module when finished */
#define CCHVLD 128 /* chat-channel value is valid */
#define SQLFLS(u) sqlflg[(u) > 31] /* squelch flags bank, as func of user# */
#define SQLBIT(u) (1<<((u)&0x1F))
/*--- OPTIONS FROM MJRTLC.MSG ---*/
int npaymx, /* max times can talk per session if no pay */
nswchx, /* max times can switch chans or on-off/15sec*/
pagint, /* minimum interval between paging a user */
reqint, /* minimum interval bewteen requesting a user*/
tinpsz; /* allowable input size for teleconference */
unsigned maxfre; /* top freeloader telecon channel */
initlc() /* initialize teleconference module */
{
int tlctck();
long lngopt();
int n;
tlcmb=opnmsg("mjrtlc.mcv");
tlclst=(struct tlc *)alcmem(n=nterms*sizeof(struct tlc));
setmem(tlclst,n,0);
npaymx=numopt(NPAYMX,0,32767);
nswchx=numopt(NSWCHX,1,32767);
maxfre=(unsigned)lngopt(MAXFRE,1L,65535L);
pagint=numopt(PAGINT,0,32767);
reqint=numopt(REQINT,0,32767);
tinpsz=numopt(TINPSZ,1,255);
inimid(TLCSTT,TLCSEL,TLCMNU);
rtkick(10,tlctck);
}
joint(chan) /* join teleconference from other module*/
unsigned chan;
{
tlcptr=&tlclst[usrnum];
tlcptr->retstt=usrptr->state;
tlcptr->retsub=usrptr->substt;
tlcptr->flags|=XTOOTH;
tlcptr->channel=chan;
usrptr->state=TLCSTT;
usrptr->substt=0;
telecn();
}
telecn() /* main teleconferencing input handler */
{
long actchn;
struct tlc *tp;
setmbk(tlcmb);
tlcptr=&tlclst[usrnum];
switch (usrptr->substt) {
case 0:
usrptr->substt=1;
btumil(usrnum,tinpsz);
btuxnf(usrnum,0,19);
prfmsg(ENTTLC,usaptr->userid);
outtlc();
prfmsg(INTRO,bbsttl);
tlcctx();
btupmt(usrnum,':');
break;
case 1:
if (margc == 0) {
tlcctx();
break;
}
if (margc == 1) {
if (sameas(margv[0],"?")
|| sameas(margv[0],"'?'")
|| sameas(margv[0],"\"?\"")
|| sameas(margv[0],"help")) {
prfmsg(TLCHLP,(pagint+30)/60);
break;
}
if (sameas(margv[0],"nopage")) {
tlcptr->flags|=NOPAGE;
prfmsg(PAGTOF);
break;
}
if (sameas(margv[0],"exit") || sameas(margv[0],"x")) {
if ((tlcptr->flags&JUSTEX) && !(usrptr->flags&OPCHAT)) {
prfmsg(NANNOY);
break;
}
tlcptr->flags|=JUSTEX;
prfmsg(LVITLC,usaptr->userid);
outtlc();
prfmsg(EXITLC);
rstrxf();
btupmt(usrnum,0);
if (tlcptr->flags&XTOOTH) {
tlcptr->flags&=~XTOOTH;
usrptr->state=tlcptr->retstt;
usrptr->substt=tlcptr->retsub;
injacr();
return(1);
}
return(0);
}
if (sameas(margv[0],"scan")) {
prf("USER-ID ..... CHANNEL ... TOPIC\r");
for (tp=tlclst,othusn=0 ; othusn < nterms ; tp++,othusn++) {
if (user[othusn].state == TLCSTT) {
prf("%-10s... ",usracc[othusn].userid);
if (user[othusn].substt == 2) {
prf("(Chat)\r");
}
else {
if ((tp->flags&SHWCHN) || (usrptr->flags&ISYSOP)
|| tp->channel == 0
|| *sigtpc(tp->channel) != '\0'
|| (!(tp->flags&LUISSU)
&& tp->modchn == tp->channel)) {
prf("%5u",tp->channel+1);
ckmodr(tp," ");
}
else {
prf("(Unlisted)");
ckmodr(tp,"");
}
}
}
}
break;
}
if (sameas(margv[0],"unlist")) {
tlcptr->flags&=~SHWCHN;
tlcptr->flags|=LUISSU;
prfmsg(UNLSTC);
break;
}
if (sameas(margv[0],"list")) {
tlcptr->flags|=(SHWCHN+LUISSU);
prfmsg(LSTCHN);
break;
}
}
if (margc == 2) {
if (sameas(margv[0],"squelch")) {
squsqu(1);
break;
}
if (sameas(margv[0],"unsquelch")) {
squsqu(0);
break;
}
}
if (margc <= 2) {
if (sameas(margv[0],"appoint")) {
xfrcon();
break;
}
if (sameas(margv[0],"chat")) {
chat();
break;
}
if (sameas(margv[0],"channel")) {
if (margc == 1) {
prfmsg(WHATCH,tlcptr->channel+1);
}
else if (strlen(margv[1]) > 5
|| (actchn=atol(margv[1])) > 65535L || actchn <= 0L) {
prfmsg(OUTORG);
}
else if (actchn == tlcptr->channel+1) {
prfmsg(YOURCH);
}
else if (actchn > maxfre && usrptr->class < PAYING) {
prfmsg(PAYONL,maxfre);
}
else if (tlcptr->swchan++ >= nswchx) {
prfmsg(NANNOY);
}
else {
prfmsg(LEFTCH,usaptr->userid);
outtlc();
tlcptr->flags&=~SQUCHD;
tlcptr->channel=(unsigned)actchn-1;
ck4sql();
prfmsg(CAMEIN,usaptr->userid);
outtlc();
tlcctx();
}
break;
}
}
if (usrptr->pfnacc > MAXPFN) {
btuinj(usrnum,RING);
return(1);
}
if (pfnlvl >= 2 && usrptr->pfnacc > WRNPFN) {
prfmsg(RAUNCH);
break;
}
if (pfnlvl > 2) {
prfmsg(PFNWRD);
break;
}
if (sameas(margv[0],"page")) {
page();
break;
}
if (sameas(margv[0],"moderate")) {
if (margc == 1) {
xfrcon();
}
else if (tlcptr->channel == 0) {
prfmsg(NOMCH1);
}
else if (*sigtpc(tlcptr->channel) != '\0') {
prfmsg(NOOVRS);
}
else if (ck4mod()) {
prfmsg(ANOMOD,usracc[othusn].userid);
}
else if (usrptr->class < PAYING) {
prfmsg(MODLIV);
}
else {
rstrin();
*(margv[1]+TPCSIZ-1)='\0';
strcpy(tlcptr->topic,margv[1]);
tlcptr->modchn=tlcptr->channel;
prfmsg(BGNCON,usaptr->userid,tlcptr->topic);
outtlc();
prfmsg(BMODER,tlcptr->topic);
}
break;
}
if (tlcptr->flags&SQUCHD) {
prfmsg(TLKSQU);
break;
}
if (usrptr->class < PAYING && (tlcptr->inpcnt)++ >= npaymx) {
prfmsg(NPAYXC,npaymx);
break;
}
if (sameas(margv[0],"whisper")) {
if (margc < 4) {
prfmsg(WHSFMT);
}
else {
whisper(margv[2],margv[3]);
}
break;
}
if (margv[0][0] == '/') {
if (margc < 2 || margv[0][1] == '\0') {
prfmsg(WHSFMT);
}
else {
whisper(margv[0]+1,margv[1]);
}
break;
}
rstrin();
prf("***\rFrom %s: %s\r",usaptr->userid,input);
outtlc();
if (chncnt() == 1) {
prfmsg(BYSELF,tlcptr->channel+1);
}
else {
prf("-- Message sent --\r");
}
break;
case 2:
if (margc == 1 && sameas(margv[0],"x")) {
tlcptr->flags&=~CCHVLD;
tlcptr->reqcha=0;
btuchi(usrnum,NULL);
btuchi(tlcptr->chatch,NULL);
btucli(usrnum);
btumil(usrnum,tinpsz);
prfmsg(ENTTLC,usaptr->userid);
outtlc();
usrptr->substt=1;
prfmsg(EXICHA);
tlcctx();
btupmt(usrnum,':');
}
else {
return(1);
}
break;
}
outprf(usrnum);
return(1);
}
char
tlchat(chan,c) /* bypass routine for btuchi() for chat */
int chan;
char c;
{
int oth;
oth=tlclst[chan].chatch;
c&=eurmsk;
switch (c) {
case '\r':
chiinp(oth,c);
chiout(oth,c);
chiout(oth,'\n');
return(c);
case '\b':
chiinp(oth,c);
chiout(oth,c);
chiout(oth,' ');
chiout(oth,c);
return(c);
default:
if (c >= 32) {
chiinp(oth,c);
chiout(oth,c);
return(c);
}
}
return(0);
}
ck4sql() /* check to see if a user is squelched */
{
for (tptr=tlclst,othusn=0 ; othusn < nterms ; tptr++,othusn++) {
if (tptr->modchn != 0 && tptr->modchn == tlcptr->channel
&& (tptr->SQLFLS(usrnum)&SQLBIT(usrnum))) {
tlclst[usrnum].flags|=SQUCHD;
}
}
}
ck4mod() /* check for a channel moderator */
{
for (tptr=tlclst,othusn=0 ; othusn < nterms ; tptr++,othusn++) {
if (tptr->modchn == tlcptr->channel && othusn != usrnum) {
if (tptr->modchn != 0) {
return(1);
}
}
}
return(0);
}
squsqu(squel) /* squelch/unsquelch user utility */
int squel;
{
if ((tlcptr->modchn != 0 && tlcptr->channel == tlcptr->modchn)
|| (usrptr->flags&ISYSOP)) {
if (instat(margv[1],TLCSTT) && othusp->substt == 1
&& tlclst[othusn].channel == tlcptr->channel) {
if (squel) {
tlcptr->SQLFLS(othusn)|=SQLBIT(othusn);
tlclst[othusn].flags|=SQUCHD;
prfmsg(YOUSQU);
outprf(othusn);
prfmsg(CHIMSQ,othuap->userid);
outbt2(othusn);
prfmsg(HESSQU,othuap->userid);
}
else {
tlcptr->SQLFLS(othusn)&=~SQLBIT(othusn);
tlclst[othusn].flags&=~SQUCHD;
prfmsg(YOUUSQ);
outprf(othusn);
prfmsg(CHEUSQ,othuap->userid);
outbt2(othusn);
prfmsg(HESUSQ,othuap->userid);
}
}
else {
prfmsg(WHSNHR,margv[1]);
}
}
else {
prfmsg(NOTMOD,(ck4mod() ? usracc[othusn].userid : "nobody"));
}
}
xfrcon() /* transfer of channel moderatorship */
{
struct tlc *otptr;
if (tlcptr->channel == tlcptr->modchn && tlcptr->modchn != 0) {
if (margc == 1) {
tlcptr->modchn=0;
prfmsg(ENDCON,usaptr->userid);
outtlc();
prfmsg(RESIGN);
}
else if (instat(margv[1],TLCSTT) && othusp->substt == 1
&& tlclst[othusn].channel == tlcptr->channel) {
otptr=&tlclst[othusn];
if (otptr->modchn != 0) {
prfmsg(ALRMOD,otptr->modchn+1);
}
else {
otptr->flags&=~SQUCHD;
otptr->modchn=otptr->channel;
strcpy(otptr->topic,tlcptr->topic);
tlcptr->modchn=0;
prfmsg(UBMODR,usaptr->userid);
outprf(othusn);
prfmsg(NEWMOD,usaptr->userid,othuap->userid);
outbt2(othusn);
prfmsg(RESIGN);
}
}
else {
prfmsg(WHSNHR,margv[1]);
}
}
else {
prfmsg(NOTMOD,(ck4mod() ? usracc[othusn].userid : "nobody"));
}
}
outbt2(chn) /* prf() to all but usrnum and chn */
unsigned chn;
{
for (othusn=0,othusp=user ; othusn < nterms ; othusn++,othusp++) {
if (othusn != usrnum && othusp->state == TLCSTT
&& othusp->substt == 1 && othusn != chn) {
if (tlclst[usrnum].channel == tlclst[othusn].channel) {
outprf(othusn);
}
}
}
clrprf();
}
ckmodr(tp,spcs) /* check for/display moderation topic */
struct tlc *tp;
char *spcs;
{
char *stp;
if (tp->channel != 0) {
if (*(stp=sigtpc(tp->channel)) != '\0') {
prf("%s %s",spcs,stp);
}
else if (tp->channel == tp->modchn) {
prf("%s %s",spcs,tp->topic);
}
}
prf("\r");
}
tlcctx() /* teleconference channel user display */
{
char *tlsrui(),*curguy,tmpbuf[16],*stp;
unsigned chan;
initls();
chan=tlclst[usrnum].channel+1;
switch (chncnt()) {
case 1:
prfmsg(BYSELF,chan);
break;
case 2:
prfmsg(ONEOTH,tlsrui(),chan);
break;
case 3:
strcpy(tmpbuf,tlsrui());
prfmsg(TWOOTH,tmpbuf,tlsrui(),chan);
break;
default:
strcpy(tmpbuf,tlsrui());
while ((curguy=tlsrui()) != NULL) {
prf("%s, ",tmpbuf);
strcpy(tmpbuf,curguy);
}
prfmsg(SEVOTH,tmpbuf,chan);
}
if (ck4mod()) {
prfmsg(CHNTPC,tptr->topic,usracc[othusn].userid);
}
else if (*(stp=sigtpc(tlcptr->channel)) != '\0') {
prfmsg(STOPIC,stp);
}
if (tlcptr->modchn != 0) {
if (tlcptr->channel == tlcptr->modchn) {
prfmsg(URMODR,tlcptr->topic);
}
else {
prfmsg(URMODO,tlcptr->modchn+1,tlcptr->topic);
}
}
prfmsg(IROEPI);
}
page() /* "page" function */
{
char *heshe();
if (margc == 1) {
prfmsg(PAGFMT);
}
else if (!onsys(margv[1])) {
if (sameas(margv[1],"on")) {
tlcptr->flags&=~(NOPAGE+OKPAGE);
prfmsg(PAGTON,(pagint+30)/60);
}
else if (sameas(margv[1],"off")) {
tlcptr->flags|=NOPAGE;
prfmsg(PAGTOF);
}
else if (sameas(margv[1],"ok")) {
tlcptr->flags|=OKPAGE;
tlcptr->flags&=~NOPAGE;
prfmsg(PAGTOK,(pagint+30)/60);
}
else if (sameas(margv[1],"Sysop")) {
prfmsg(PAGEOK,"Sysop (at main console)");
tlcptr->blinkc=8;
shochb(usaptr->userid,1);
}
else {
prfmsg(PAGNON,margv[1]);
}
}
else if (tlclst[othusn].flags&NOPAGE) {
prfmsg(PAGOFF,othuap->userid);
}
else if (!(tlclst[othusn].flags&OKPAGE) && tlclst[othusn].paged) {
prfmsg(PAGL2M,othuap->userid,(pagint+30)/60);
}
else if (othusp->state == TLCSTT && othusp->substt == 1 &&
tlclst[othusn].channel == tlcptr->channel) {
prfmsg(PAGATC,othuap->userid,heshe(othusn));
}
else {
if (margc == 2) {
prfmsg(PAGMSG,usaptr->userid,tlcptr->channel+1);
}
else {
rstrin();
prfmsg(PAGNOT,usaptr->userid,tlcptr->channel+1,margv[2]);
}
if (injoth()) {
tlclst[othusn].paged=(pagint+7)/15;
prfmsg(PAGEOK,othuap->userid);
}
else {
prfmsg(PAGNPS,othuap->userid);
}
}
}
chat() /* "chat" function */
{
int i;
char tlchat();
if (margc == 1) {
prfmsg(CHAFMT);
}
else if (!onsys(margv[1])) {
prfmsg(PAGNON,margv[1]);
}
else if (user[othusn].state != TLCSTT) {
prfmsg(NOLINT,othuap->userid);
}
else if (user[othusn].substt == 2) {
prfmsg(ALRICH,othuap->userid);
}
else if (othusn == usrnum) {
prfmsg(NCHSLF);
}
else if ((tlclst[othusn].flags&CCHVLD)
&& usrnum == tlclst[othusn].chatch) {
tlclst[usrnum].chatch=othusn;
btumil(othusn,-(othuap->scnwid-1));
btumil(usrnum,-(usaptr->scnwid-1));
usrptr->substt=2;
othusp->substt=2;
tlcptr=&tlclst[othusn];
i=usrnum;
usrnum=othusn;
prfmsg(GONCHA,othuap->userid);
outtlc();
btucli(othusn);
btuclo(othusn);
btupmt(othusn,0);
prfmsg(ACCPCH,usaptr->userid);
prfmsg(ENTCHA);
outprf(othusn);
btuchi(othusn,tlchat);
usrnum=i;
btuclo(usrnum);
btucli(usrnum);
tlcptr=&tlclst[usrnum];
prfmsg(GONCHA,usaptr->userid);
outtlc();
btupmt(usrnum,0);
prfmsg(ENTCHA);
btuchi(usrnum,tlchat);
}
else if (tlclst[othusn].flags&NOPAGE) {
prfmsg(PAGOFF,othuap->userid);
}
else if (!(tlclst[othusn].flags&OKPAGE) && tlclst[othusn].reqcha) {
prfmsg(CHAL2M,othuap->userid,(reqint+30)/60);
}
else {
prfmsg(CHAREQ,usaptr->userid,(usaptr->sex == 'M' ? "him" : "her"),
usaptr->userid);
if (injoth()) {
tlcptr->chatch=othusn;
tlcptr->flags|=CCHVLD;
tlclst[othusn].reqcha=(reqint+7)/15;
prfmsg(CREQOK,othuap->userid);
}
else {
prfmsg(PAGNPS,othuap->userid);
}
}
}
chncnt() /* count number of users on channel */
{
int i,cnt;
unsigned chan;
chan=tlclst[usrnum].channel;
for (i=0,cnt=0 ; i < nterms ; i++) {
if (user[i].state == TLCSTT && user[i].substt == 1
&& tlclst[i].channel == chan) {
cnt+=1;
}
}
return(cnt);
}
char *heshe(usr) /* returns "he" or "she" for a user */
int usr;
{
return(usracc[usr].sex == 'M' ? "he" : "she");
}
whisper(whoto,what) /* "whisper" function */
char *whoto,*what;
{
if (!instat(whoto,TLCSTT) || othusp->substt != 1
|| tlclst[othusn].channel != tlclst[usrnum].channel) {
prfmsg(WHSNHR,whoto);
}
else {
rstrin();
prfmsg(WHSTO,usaptr->userid,what);
outprf(othusn);
prf("-- Message sent only to %s --\r",othuap->userid);
}
}
outtlc() /* prf()s prfbuf to teleconference chan */
{
int ousn;
struct user *ousp;
for (ousn=0,ousp=user ; ousn < nterms ; ousn++,ousp++) {
if (ousn != usrnum && ousp->state == TLCSTT && ousp->substt == 1) {
if (tlcptr->channel == tlclst[ousn].channel) {
outprf(ousn);
}
}
}
clrprf();
}
tlctck() /* real-time teleconference kicker */
{
struct tlc *tlcptr;
for (usrnum=0,tlcptr=tlclst ; usrnum < nterms ; usrnum++,tlcptr++) {
if (tlcptr->paged != 0) {
tlcptr->paged-=1;
}
if (tlcptr->blinkc != 0) {
if ((tlcptr->blinkc-=1) == 0) {
shochn(usracc[usrnum].userid);
}
}
if (tlcptr->reqcha != 0) {
tlcptr->reqcha-=1;
}
tlcptr->swchan=0;
tlcptr->flags&=~JUSTEX;
}
rtkick(15,tlctck);
}
initls() /* initialize teleconferencer list */
{
othusn=-1;
othusp=user-1;
othuap=usracc-1;
tptr=tlclst-1;
}
char *tlsrui() /* teleconferencer list, show next one */
{
static char retval[16];
while (othusn < nterms) {
othusn+=1;
othusp+=1;
othuap+=1;
tptr+=1;
if (othusp->state == TLCSTT && othusn != usrnum &&
othusp->substt == 1 && tptr->channel == tlcptr->channel) {
strcpy(retval,othuap->userid);
if (tptr->flags&SQUCHD) {
strcat(retval," (sq)");
}
return(retval);
}
}
return(NULL);
}
tlchup() /* teleconference hang-up routine */
{
int i,othusn;
tlcptr=&tlclst[usrnum];
if (usrptr->state == TLCSTT) {
setmbk(tlcmb);
if (usrptr->substt == 2) {
othusn=tlcptr->chatch;
btuchi(usrnum,NULL);
btuchi(othusn,NULL);
tlcptr=&tlclst[othusn];
tlcptr->flags&=~CCHVLD;
tlcptr->reqcha=0;
btupmt(othusn,':');
user[othusn].substt=1;
prfmsg(ENTTLC,usracc[othusn].userid);
i=usrnum;
usrnum=othusn;
outtlc();
prfmsg(OCHHUP,usaptr->userid);
tlcctx();
outprf(othusn);
btucli(othusn);
btumil(othusn,tinpsz);
usrnum=i;
tlcptr=&tlclst[usrnum];
}
else {
prfmsg(TLCHUP,usaptr->userid);
outtlc();
}
}
for (tptr=tlclst,othusn=0 ; othusn < nterms ; tptr++,othusn++) {
if (tptr->chatch == usrnum) {
tptr->flags&=~CCHVLD;
}
tptr->SQLFLS(usrnum)&=~SQLBIT(usrnum);
}
setmem(tlcptr,sizeof(struct tlc),0);
}
clstlc() /* close teleconference files for shutdown */
{
clsmsg(tlcmb);
}