/***************************************************************************
 *                                                                         *
 *   TLCUTL.C                                                              *
 *                                                                         *
 *   Copyright (c) 1994-1997 Galacticomm, Inc.    All Rights Reserved.     *
 *                                                                         *
 *   Common utility routines between MJRTLC.C and CSMJRTLC.C.              *
 *                                                                         *
 *                                            - Bill Hyatt 10/4/94         *
 *                                                                         *
 ***************************************************************************/

#include "tlc.h"

#define FILREV "$Revision: 11 $"

static VOID fmtdpk(INT typ,CHAR *dpksfx,CHAR *datbuf,
             CHAR *parm1,CHAR *parm2,CHAR *parm3);
static VOID supcht(INT unum,INT onum);
static VOID xitutl(INT orgguy,GBOOL othguy,GBOOL hangup);

INT
chncnt(VOID)                       /* count number of users on channel     */
{
     INT cnt=0,ousn;
     UINT chan;
     struct user *ousp;

     chan=tlclst[usrnum].channel;
     for (ousn=0 ; ousn < nterms ; ousn++) {
       ousp=usroff(ousn);
          if (ousp->flags&ISGCSU) {
               if (tlclst[ousn].flags&TLCGCS && tlclst[ousn].channel == chan) {
                    if (!(ousp->flags&INVISB) || ousn == usrnum) {
                         cnt++;
                    }
               }
          }
          else {
               if (ousp->state == tlcstt && ousp->substt == 1
             && tlclst[ousn].channel == chan) {
                    if (!(ousp->flags&INVISB) || ousn == usrnum) {
                         cnt++;
                    }
               }
          }
     }
     return(cnt);
}

VOID
initls(VOID)                       /* initialize teleconferencer list      */
{
     othusn=-1;
     tptr=tlclst-1;
}

CHAR *
tlsrui(                            /* teleconferencer list, get next one   */
INT lsttyp)                        /*   type of list being built           */
{
     static CHAR retval[UIDSIZ+6];
     GBOOL incl=FALSE;

     while (othusn < nterms-1) {
          othusn++;
          othusp=usroff(othusn);
          othuap=uacoff(othusn);
          tptr++;
          if (othusn != usrnum && !(othusp->flags&INVISB)
           && ((othusp->flags&ISGCSU && tptr->flags&TLCGCS)
            || (othusp->state == tlcstt && othusp->substt == 1))) {
               switch (lsttyp) {
            case LSTALL:
                    incl=TRUE;
                    break;
               case LSTSCH:
                    incl=tptr->channel == tlcptr->channel;
                    break;
               case LSTCS:
                    incl=(othusp->flags&ISGCSU) > 0;
                    break;
               case LSTCRQ:
                    incl=tptr->chatch == usrnum;
                    break;
               }
               if (incl) {
                    strcpy(retval,othuap->userid);
                    if (!(usrptr->flags&ISGCSU) && tptr->flags&SQUCHD) {
                         strcat(retval,"(sq)");
                    }
                    return(retval);
               }
          }
     }
     return(NULL);
}

GBOOL
inscan(                            /* should user be in tele scan?         */
INT unum,                          /*   user num in question               */
struct tlc *tp)                    /*   tele info for user                 */
{
     if (usroff(unum)->flags&ISGCSU && tp->flags&(TLCGCS|TLCCHT)) {
          return(!(usroff(unum)->flags&INVISB));
     }
     if (!(usroff(unum)->flags&ISGCSU) && usroff(unum)->state == tlcstt) {
          return(!(usroff(unum)->flags&INVISB));
     }
     return(FALSE);
}

CHAR *
scnchn(                            /* what to disp for chan in tele scan   */
INT unum,                          /*   user num in ques                   */
struct tlc *tp)                    /*   tele info for user                 */
{
     if ((usroff(unum)->flags&ISGCSU && tp->flags&TLCCHT)
      || (!(usroff(unum)->flags&ISGCSU) && usroff(unum)->substt == 2)) {
          return("(Chat)");
     }
     if (tp->flags&SHWCHN || usrptr->flags&MASTER
      || tp->channel == 0 || fidxst(tp->channel)
      || (!(tp->flags&LUISSU) && tp->modchn == tp->channel)) {
          if (usrptr->flags&ISGCSU) {
               return(spr("%u",tp->channel+1));
          }
          else {
               return(spr("%5u",tp->channel+1));
          }
     }
     return("(Unlisted)");
}

CHAR *
scntpc(                            /* what to disp for topic in tele scan  */
struct tlc *tp)                    /*   tele info for user                 */
{
     const CHAR *stp;

     if ((stp=getftpc(tp->channel)) != NULL) {
          return(spr("%s",stp));
     }
     if (tp->channel == tp->modchn) {
          return(tp->topic);
     }
     return(NULL);
}

INT
urinv(VOID)                        /* can't execute command while invisible*/
{
     if (usrptr->flags&INVISB) {
          if (usrptr->flags&ISGCSU) {
               prf("INV");
          }
          prfmsg(URINVS);
          return(TRUE);
     }
     return(FALSE);
}

INT
howmny(                            /* number of people starting w/ stg?    */
CHAR *stg,                         /* stg to use in sameto() test          */
INT prec,                          /* how precise should this be? 0-2      */
GBOOL samas)                       /* take sameas() as a return(1)?        */
{
     INT cnt=0,dstusn;

     for (othusn=0 ; othusn < nterms ; othusn++) {
       othusp=usroff(othusn);
          othuap=uacoff(othusn);
          switch (prec) {
          case 2:
               if (tlclst[othusn].channel != tlclst[usrnum].channel) {
                    break;
               }
          case 1:
               if (!((othusp->flags&ISGCSU && tlclst[othusn].flags&TLCGCS)
                     || (othusp->state == tlcstt && othusp->substt == 1))) {
                    break;
               }
          case 0:
               if (othusp->flags&INVISB || othusp->usrcls < SUPLON
             || !sameto(stg,othuap->userid)) {
                    break;
               }
               if (samas && sameas(stg,othuap->userid)) {
                    return(1);
               }
               dstusn=othusn;
               cnt++;
          }
     }
     if (cnt == 1) {
          othusn=dstusn;
          othusp=usroff(othusn);
          othuap=uacoff(othusn);
     }
     return(cnt);
}

INT
ck4mod(                            /* check for a channel moderator        */
INT excusr)                        /*   user to exclude from search        */
{
     for (tptr=tlclst,othusn=0 ; othusn < nterms ; tptr++,othusn++) {
          if (tptr->modchn == tlcptr->channel && othusn != excusr) {
               if (tptr->modchn != 0) {
                    return(1);
               }
          }
     }
     return(0);
}

GBOOL
xfrmod(                            /* transfer of channel moderatorship    */
CHAR *uid)                         /*   user to transfer to                */
{
     struct tlc *otptr;
     GBOOL iscs;

     if (urinv()) {
          return(FALSE);
     }
     iscs=(usrptr->flags&ISGCSU) != 0;
     if (tlcptr->channel != tlcptr->modchn || tlcptr->modchn == 0) {
          if (iscs) {
               prf("NMD");
          }
          prfmsg(NOTMOD,(ck4mod(usrnum) ? uacoff(othusn)->userid : "nobody"));
          return(FALSE);
     }
     if (uid == NULL) {
          tlcptr->modchn=0;
          outtlc(ENDCON,ALLU,usrnum,-1,usaptr->userid,NULL,NULL);
          if (iscs) {
               prf("RES");
          }
          prfmsg(RESIGN);
          return(TRUE);
     }
     if (!onsys(uid) ||
      !(((othusp->flags&ISGCSU && tlclst[othusn].flags&TLCGCS)
         || (othusp->state == tlcstt && othusp->substt == 1))
        && tlclst[othusn].channel == tlcptr->channel)) {
          if (iscs) {
               prf("NHR");
          }
          prfmsg(WHSNHR,uid);
          return(FALSE);
     }
     otptr=&tlclst[othusn];
     if (otptr->modchn != 0) {
          if (iscs) {
               prf("ALM");
          }
          prfmsg(ALRMOD,otptr->modchn+1);
          return(FALSE);
     }
     otptr->flags&=~SQUCHD;
     otptr->modchn=otptr->channel;
     strcpy(otptr->topic,tlcptr->topic);
     tlcptr->modchn=0;
     if (othusp->flags&ISGCSU) {
          cnvd2s(spr("sa=%s;u=%s;:ubmodr",TLCAID,othuap->userid),namtmp);
          if (qroom(othusn,NORMAL)) {
               senddpk(othusn,TLCAID,NORMAL,namtmp,STGLEN,usaptr->userid,NULL);
          }
     }
     else {
          prfmlt(UBMODR,usaptr->userid);
          prfmlt(TLCPMT);
          outmlt(othusn);
     }
     outtlc(NEWMOD,ALLU,usrnum,othusn,usaptr->userid,othuap->userid,NULL);
     if (iscs) {
          prf("RES");
     }
     prfmsg(RESIGN);
     return(TRUE);
}

VOID
ntfyres(                           /* notify former chan of modrtr resign  */
UINT excchn)                       /*    channel to exclude                */
{
     UINT savchn;

     if (tlcptr->modchn != 0 && tlcptr->modchn != excchn) {
          savchn=tlcptr->channel;
          tlcptr->channel=tlcptr->modchn;
          outtlc(ENDCON,ALLU,usrnum,-1,usaptr->userid,NULL,NULL);
          tlcptr->channel=savchn;
     }
}

GBOOL
squsqu(                            /* squelch/unsquelch user utility       */
CHAR *uid,                         /*   user to squelch/unsquelch          */
GBOOL squel)                       /*   TRUE=squelch  FALSE=unsquelch      */
{
     INT indx;
     LONG cbit;
     GBOOL iscs;

     iscs=(usrptr->flags&ISGCSU) != 0;
     if (!onsys(uid)) {
          if (iscs) {
               prf("NHR");
          }
          prfmsg(WHSNHR,uid);
          return(FALSE);
     }
     if ((tlcptr->modchn == 0 || tlcptr->channel != tlcptr->modchn)
      && !(usrptr->flags&MASTER)) {
          if (iscs) {
               prf("NMD");
          }
          prfmsg(NOTMOD,(ck4mod(usrnum) ? uacoff(othusn)->userid : "nobody"));
          return(FALSE);
     }
     if (!(((othusp->flags&ISGCSU && tlclst[othusn].flags&TLCGCS)
         || (othusp->state == tlcstt && othusp->substt == 1))
        && tlclst[othusn].channel == tlcptr->channel)) {
          if (iscs) {
               prf("NHR");
          }
          prfmsg(WHSNHR,uid);
          return(FALSE);
     }
     indx=othusn/32;
     cbit=1L<<(othusn&0x1F);
     if (squel) {
          tlcptr->sqlflg[indx]|=cbit;
          tlclst[othusn].flags|=SQUCHD;
          if (othusp->flags&ISGCSU) {
               cnvd2s(spr("sa=%s;u=%s;:yousqu",TLCAID,othuap->userid),namtmp);
               if (qroom(othusn,NORMAL)) {
                    senddpk(othusn,TLCAID,NORMAL,namtmp,0,NULL,NULL);
               }
          }
          else {
               prfmlt(YOUSQU);
               prfmlt(TLCPMT);
               outmlt(othusn);
          }
          outtlc(CHIMSQ,ALLU,usrnum,othusn,othuap->userid,NULL,NULL);
          if (iscs) {
               prf("HSQ");
          }
          prfmsg(HESSQU,othuap->userid);
     }
     else {
          tlcptr->sqlflg[indx]&=~cbit;
          tlclst[othusn].flags&=~SQUCHD;
          if (othusp->flags&ISGCSU) {
               cnvd2s(spr("sa=%s;u=%s;:youusq",TLCAID,othuap->userid),namtmp);
               if (qroom(othusn,NORMAL)) {
                    senddpk(othusn,TLCAID,NORMAL,namtmp,0,NULL,NULL);
               }
          }
          else {
               prfmlt(YOUUSQ);
               prfmlt(TLCPMT);
               outmlt(othusn);
          }
          outtlc(CHEUSQ,ALLU,usrnum,othusn,othuap->userid,flgbyt(othusn),NULL);
          if (iscs) {
               prf("USQ");
          }
          prfmsg(HESUSQ,othuap->userid);
     }
     return(TRUE);
}

INT
chkchn(                            /* check if ok to switch to new chan    */
LONG newchn)                       /*   tele channel to switch to          */
{
     if (newchn < 1L || newchn > 65535L) {
          return(OUTORG);
     }
     if (newchn == tlcptr->channel+1) {
          return(YOURCH);
     }
     if (!(usrptr->flags&ISGCSU)
      && fidxst(tlcptr->channel) && !swtfrm
      && !(usrptr->flags&MASTER)) {
          return(CANTLV);
     }
     if (fidxst((UINT)newchn-1)
      && ((usrptr->flags&ISGCSU && !cswto) || (!(usrptr->flags&ISGCSU)
                                && !swtfrm))
      && !(usrptr->flags&MASTER)) {
          return(CANTGO);
     }
     if (fidxst((UINT)newchn-1) && !faccok((UINT)newchn-1)
      && !(usrptr->flags&MASTER)) {
          return(PRVLCH);
     }
     if (newchn > maxfre && !haskey(unlkey)) {
          return(PAYONL);
     }
     if (tlcptr->swchan++ >= nswchx) {
          return(NANNOY);
     }
     return(CHANOK);
}

VOID
swtchn(                            /* switch user to new tele channel      */
LONG newchn)                       /*   channel to switch to               */
{
     if (!(usrptr->flags&INVISB)) {
          outtlc(LEFTCH,ALLU,usrnum,-1,usaptr->userid,NULL,NULL);
     }
     tlcptr->flags&=~SQUCHD;
     tlcptr->channel=(UINT)newchn-1;
     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;
          }
     }
     if (!(usrptr->flags&INVISB)) {
          outtlc(CAMEIN,ALLU,usrnum,-1,usaptr->userid,flgbyt(usrnum),NULL);
     }
}

VOID
sndwsp(                            /* send whispered msg utility           */
CHAR *what)                        /*   message to send                    */
{
     CHAR datbuf[TDBFSZ];

     if (othusp->flags&ISGCSU) {
          if (qroom(othusn,NORMAL)) {
               cnvd2s(spr("sa=%s;u=%s;:whisper",TLCAID,othuap->userid),namtmp);
               stlcpy(datbuf,spr("%s\t",usaptr->userid),UIDSIZ);
               strcat(datbuf,what);
               senddpk(othusn,TLCAID,NORMAL,namtmp,STGLEN,datbuf,NULL);
          }
     }
     else {
          prfmlt(WHSTO,usaptr->userid,what);
          prfmlt(TLCPMT);
          outmlt(othusn);
     }
     if (!(usrptr->flags&ISGCSU)) {
          prfmsg(WHSSNT,othuap->userid);
     }
}

INT
chkcht(                            /* check if a chat request is ok        */
CHAR *uid)                         /*   userid to chat with                */
{
     INT count,othpset,savusr;

     if (urinv()) {
          return(URINVS);
     }
     if (uid[0] == '\0') {
          return(CHAFMT);
     }
     if ((count=howmny(uid,1,1)) == 0) {
          return(WHSNHR);
     }
     if (count != 1) {
          return(AMBIG);
     }
     if (othusn == usrnum) {
          return(NCHSLF);
     }
     if (usrptr->flags&ISGCSU && !(othusp->flags&ISGCSU)) {
          return(NOCHAA2);
     }
     if (!(usrptr->flags&ISGCSU) && othusp->flags&ISGCSU) {
          return(NOCHCS2);
     }
     if ((tlclst[othusn].flags&CCHVLD) && usrnum == tlclst[othusn].chatch) {
          return(ENTCHA);
     }
     savusr=usrnum;
     curusr(othusn);
     othpset=(*pageset)();
     curusr(savusr);
     if (othpset == PAGE_OFF) {
          return(CHTOFF);
     }
     if (othpset != PAGE_OK && tlclst[othusn].reqcha) {
          return(CHAL2M);
     }
     return(CHAREQ);
}

VOID
reqcht(VOID)                       /* send chat request to othusn          */
{
     GBOOL reqok;

     if (othusp->flags&ISGCSU) {
          cnvd2s(spr("sa=%s;u=%s;:chtreq",TLCAID,othuap->userid),namtmp);
          senddpk(othusn,TLCAID,NORMAL,namtmp,STGLEN,
                  spr("%s%c",usaptr->userid,tlcsex(usaptr->sex)),NULL);
          reqok=TRUE;
     }
     else {
          prfmlt(CHAREQ,usaptr->userid,tlcsxp(usaptr->sex),usaptr->userid);
          reqok=injoth();
     }
     if (reqok) {
          rmvcht(othusn);
          tlcptr->chatch=othusn;
          tlcptr->flags|=CCHVLD;
          tlclst[othusn].reqcha=(reqint+7)/15;
          if (usrptr->flags&ISGCSU) {
               prf("REQ");
          }
          else {
               prfmsg(CREQOK,othuap->userid);
          }
     }
     else {
          if (usrptr->flags&ISGCSU) {
               prf("NPS");
          }
          prfmsg(CHTNPS,othuap->userid);
     }
}

VOID
rmvcht(                            /* rem cur user fm tlcptr->chatch's list*/
INT excusr)                        /*   don't remove from this user's list */
{
     if (tlcptr->flags&CCHVLD
      && tlcptr->chatch != excusr && usroff(tlcptr->chatch)->flags&ISGCSU) {
          cnvd2s(spr("sa=%s;u=%s;:unchtreq",TLCAID,
                     uacoff(tlcptr->chatch)->userid),namtmp);
          senddpk(tlcptr->chatch,TLCAID,NORMAL,namtmp,STGLEN,usaptr->userid,NULL);
     }
}

VOID
enttcht(VOID)                       /* enter usrnum and othusn into chat    */
{
     rmvcht(othusn);
     tlcptr->chatch=othusn;
     supcht(usrnum,othusn);
     supcht(othusn,usrnum);
     if (othusp->flags&ISGCSU) {
          cnvd2s(spr("sa=%s;u=%s;:entcht",TLCAID,othuap->userid),namtmp);
          senddpk(othusn,TLCAID,NORMAL,namtmp,STGLEN,usaptr->userid,NULL);
     }
     else {
          prfmlt(ACCPCH,usaptr->userid);
          prfmlt(ENTCHA);
          outmlt(othusn);
          btuchi(othusn,tlchat);
     }
     if (usrptr->flags&ISGCSU) {
          prf("ENT");
     }
     else {
          prfmsg(ENTCHA);
          btuchi(usrnum,tlchat);
     }
}

static VOID
supcht(                            /* setup for chat                       */
INT unum,                          /*   user entering chat                 */
INT onum)                          /*   user he's chatting with            */
{
     struct usracc *uaptr;
     struct user *uptr;

     uaptr=uacoff(unum);
     uptr=usroff(unum);
     if (uptr->flags&ISGCSU) {
          tlclst[unum].flags&=~TLCGCS;
          tlclst[unum].flags|=TLCCHT;
          outtlc(GONCHA,ALLU,onum,-1,uaptr->userid,NULL,NULL);
     }
     else {
          tlclst[unum].flags&=~TYPING;
          btumil(unum,-(uaptr->scnwid-1));
          uptr->substt=2;
          uptr->flags|=NOGLOB;
          outtlc(GONCHA,ALLU,onum,-1,uaptr->userid,NULL,NULL);
          btucli(unum);
          btuclo(unum);
     }
}

VOID
xitcht(                            /* remove users from chat               */
GBOOL hangup)                      /*   got a hangup?                      */
{
     INT org;

     xitutl(usrnum,FALSE,hangup);
     org=usrnum;
     curusr(tlcptr->chatch);
     tlcptr=&tlclst[usrnum];
     xitutl(org,TRUE,hangup);
     curusr(org);
     tlcptr=&tlclst[usrnum];
}

static VOID
xitutl(                            /* utility to remove users from chat    */
INT orgguy,                        /*   usrnum that originally exited      */
GBOOL othguy,                      /*   handling guy that got exited on?   */
GBOOL hangup)                      /*   did user that exited hang up?      */
{
     if (usrptr->flags&ISGCSU) {
          if (hangup && !othguy) {
               return;
          }
          if (!othguy) {
               if (tlcptr->flags&TLCGCS) {
                    outtlc(ENTTLC,ALLU,usrnum,-1,usaptr->userid,
                           tlcptr->flags&DBRDUP ? "Y" : "N",NULL);
               }
          }
          else {
               tlcptr->flags|=TLCGCS;
               cnvd2s(spr("sa=%s;u=%s;:xitcht",TLCAID,usaptr->userid),namtmp);
               senddpk(usrnum,TLCAID,NORMAL,namtmp,STGLEN,
                       hangup ? "HUP" : "XIT",NULL);
               outtlc(ENTTLC,ALLU,usrnum,-1,usaptr->userid,
                      tlcptr->flags&DBRDUP ? "Y" : "N",NULL);
          }
          tlcptr->reqcha=0;
          tlcptr->flags&=~(TLCCHT|CCHVLD);
     }
     else {
          btuchi(usrnum,NULL);
          if (hangup && !othguy) {
               return;
          }
          tlcptr->flags&=~CCHVLD;
          tlcptr->reqcha=0;
          btucli(usrnum);
          btumil(usrnum,tinpsz);
          outtlc(ENTTLC,ALLU,usrnum,-1,usaptr->userid," ",NULL);
          usrptr->substt=1;
          usrptr->flags&=~NOGLOB;
          prfmsg((hangup ? OCHHP2 : EXICH2),uacoff(orgguy)->userid);
          if (hangup || !othguy || (othguy && usroff(orgguy)->flags&OPCHAT)) {
               tlcctx();
          }
          prfmsg(TLCPMT);
          outprf(usrnum);
          clrprf();
     }
}

VOID
tlchup(VOID)                       /* common C/S / A/A tele hangup routine */
{
     INT i;

     setmbk(tlcmb);
     tlcptr=&tlclst[usrnum];
     ntfyres(0);
     if (usrptr->state == tlcstt) {
          if (usrptr->substt == 2) {
               xitcht(1);
          }
          else {
               if (!(usrptr->flags&INVISB)) {
                    outtlc(TLCHUP,ALLU,usrnum,-1,usaptr->userid,NULL,NULL);
               }
          }
          rmvcht(-1);
     }
     else if (tlcptr->flags&TLCGCS) {
          if (!(usrptr->flags&INVISB)) {
               outtlc(TLCHUP,ALLU,usrnum,-1,usaptr->userid,NULL,NULL);
          }
          rmvcht(-1);
     }
     else if (tlcptr->flags&TLCCHT) {
          xitcht(1);
     }
     for (tptr=tlclst,i=0 ; i < nterms ; tptr++,i++) {
          if (tptr->chatch == usrnum) {
               tptr->flags&=~CCHVLD;
          }
          tptr->SQLFLS(usrnum)&=~SQLBIT(usrnum);
     }
     abosnd();
     aboarcvs();
     setmem(tlcptr,sizeof(struct tlc),0);
}

CHAR *
flgbyt(                            /* flag byte indicater for user lists   */
INT unum)                          /*   user number in question            */
{
     CHAR *fbyt;

     if (tlclst[unum].flags&SQUCHD) {
          fbyt="S";
     }
     else if (usroff(unum)->flags&ISGCSU) {
          fbyt=(tlclst[unum].flags&DBRDUP) ? "Y" : "N";
     }
     else {
          fbyt=" ";
     }
     return(fbyt);
}

INT
ck4pfn(VOID)                       /* check for profanity and deal with it */
{
     if (usrptr->pfnacc > MAXPFN) {
          byenow(NO_MESSAGE);
          return(HUNGUP);
     }
     if (pfnlvl >= 2 && usrptr->pfnacc > WRNPFN) {
          if (usrptr->flags&ISGCSU) {
               prf("PFN");
          }
          prfmsg(RAUNCH);
          return(WARNED);
     }
     if (pfnlvl > 2) {
          if (usrptr->flags&ISGCSU) {
               prf("PFN");
          }
          prfmsg(PFNWRD);
          return(WARNED);
     }
     return(NOPFN);
}

VOID
outtlc(                            /* send output to tele chans            */
INT msg,                           /*   msg block being used for A/A users */
INT sendto,                        /*   send to C/S, A/A, or both?         */
INT orgusr,                        /*   user num output is originating from*/
INT excusr,                        /*   user to exclude from sending       */
CHAR *parm1,                       /*   variable parameters (as in spr())  */
CHAR *parm2,
CHAR *parm3)
{
     INT ousn;
     struct user *ousp;
     CHAR datbuf[TDBFSZ];

     if (sendto == CS || sendto == ALLU) {
          stzcpy(namtmp->sysid,msysid,SIDSIZ);
          stzcpy(namtmp->appid,TLCAID,AIDSIZ);
          namtmp->flags=0x00;
          fmtdpk(msg,namtmp->suffix,datbuf,parm1,parm2,parm3);
     }
     if (sendto == AA || sendto == ALLU) {
          setmbk(tlcmb);
          prfmlt(msg,parm1,parm2,parm3);
          prfmlt(TLCPMT);
     }
     for (ousn=0 ; ousn < nterms ; ousn++) {
       ousp=usroff(ousn);
          if (ousn != orgusr && ousn != excusr) {
               if (ousp->flags&ISGCSU) {
                    if (tlclst[ousn].flags&TLCGCS
               && (sendto == CS || sendto == ALLU)
               && tlclst[orgusr].channel == tlclst[ousn].channel
               && qroom(ousn,NORMAL)) {
                         stzcpy(namtmp->usrid,uacoff(ousn)->userid,UIDSIZ);
                         senddpk(ousn,TLCAID,NORMAL,namtmp,STGLEN,datbuf,NULL);
                    }
               }
               else {
                    if (ousp->state == tlcstt && ousp->substt == 1
               && (sendto == AA || sendto == ALLU)
               && tlclst[orgusr].channel == tlclst[ousn].channel) {
                         outmlt(ousn);
                    }
               }
          }
     }
     clrmlt();
}

static VOID
fmtdpk(                            /* format dpk info for C/S users        */
INT typ,                           /*   ind's what type of info            */
CHAR *dpksfx,                      /*   dpk suffix for dpk structure       */
CHAR *datbuf,                      /*   where to put formatted info        */
CHAR *parm1,                       /*   variable parameters                */
CHAR *parm2,
CHAR *parm3)
{
     (VOID)parm3;
     datbuf[0]='\0';
     switch (typ) {
     case ENTTLC:
          stzcpy(dpksfx,"enttlc",SFXSIZ);
          stzcpy(datbuf,spr("%s%s",parm1,parm2),UIDSIZ+1);
          break;
     case NMTALK:
          stzcpy(dpksfx,"nmtalk",SFXSIZ);
          stzcpy(datbuf,spr("%s\t",parm1),UIDSIZ+1);
          strcat(datbuf,parm2);
          break;
     case DBRDUP:
          stzcpy(dpksfx,"dbrdup",SFXSIZ);
          stzcpy(datbuf,spr("%s%s",parm1,parm2),UIDSIZ+1);
          break;
     case DBRDDN:
          stzcpy(dpksfx,"dbrddn",SFXSIZ);
          stzcpy(datbuf,spr("%s%s",parm1,parm2),UIDSIZ+1);
          break;
     case CAMEIN:
          stzcpy(dpksfx,"camein",SFXSIZ);
          stzcpy(datbuf,spr("%s%s",parm1,parm2),UIDSIZ+1);
          break;
     case LEFTCH:
          stzcpy(dpksfx,"leftch",SFXSIZ);
          stzcpy(datbuf,parm1,UIDSIZ);
          break;
     case GONCHA:
          stlcpy(dpksfx,"goncha",SFXSIZ);
          stlcpy(datbuf,parm1,UIDSIZ);
          break;
     case BGNCON:
          stlcpy(dpksfx,"bgncon",SFXSIZ);
          stlcpy(datbuf,spr("%s\t%s",parm1,parm2),UIDSIZ+CTPSIZ);
          break;
     case NEWMOD:
          stlcpy(dpksfx,"newmod",SFXSIZ);
          stlcpy(datbuf,spr("%s\t%s",parm1,parm2),UIDSIZ+UIDSIZ);
          break;
     case ENDCON:
          stlcpy(dpksfx,"endcon",SFXSIZ);
          stlcpy(datbuf,parm1,UIDSIZ);
          break;
     case CHIMSQ:
          stlcpy(dpksfx,"chimsq",SFXSIZ);
          stlcpy(datbuf,parm1,UIDSIZ);
          break;
     case CHEUSQ:
          stlcpy(dpksfx,"cheusq",SFXSIZ);
          stlcpy(datbuf,spr("%s%s",parm1,parm2),UIDSIZ+1);
          break;
     case LVITLC:
          stzcpy(dpksfx,"lvitlc",SFXSIZ);
          stzcpy(datbuf,parm1,UIDSIZ);
          break;
     case TLCHUP:
          stlcpy(dpksfx,"tlchup",SFXSIZ);
          stlcpy(datbuf,parm1,UIDSIZ);
          break;
     default:
          catastro("FMTDPK: invalid value type parameter! (%d)",typ);
     }

}
