/***************************************************************************
 *                                                                         *
 *   CSREGIS.C                                                             *
 *                                                                         *
 *   Copyright (c) 1994-1997 Galacticomm, Inc.    All rights reserved.     *
 *                                                                         *
 *   This is the Registry agent.                                           *
 *                                                                         *
 *                                                - Bill Hyatt 9/4/94      *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "majorbbs.h"
#include "gcspsrv.h"
#include "registry.h"
#include "galregis.h"

#define FILREV "$Revision: 10 $"

#define   XBYTPQ    1+1+4          /* xtra bytes per ques in reg info stgs */
#define   RPFXSZ    3              /* size of "# of flds" ind in info stgs */
#define   MXRINF    MAXDPKV-RPFXSZ /* maximum size of reg info stgs        */

                         /* flags to indicate which Registry keys user has */
#define   HASAKY 0x01              /* user has registry agent access key   */
#define   HASCKY 0x02              /* user has key to create an entry      */
#define   HASVKY 0x04              /* user has key to view entries         */

#define   FLDSEP "\1"              /* field sep char for entries fm client */

static VOID regread(INT direction,struct saunam *dpknam);
static VOID regwrite(struct saunam *dpknam,USHORT length,VOID *value);
static VOID regxdone(VOID);
static VOID regabort(VOID);
static VOID makrinf(VOID);
static VOID regannou(VOID);

struct agent regagt={              /* agent information structure          */
     "GALREG",                     /* appid                                */
     regread,                      /* read-dynapak function pointer        */
     regwrite,                     /* write-dynapak function pointer       */
     regxdone,                     /* file xfer-done function pointer      */
     regabort                      /* abort-request function pointer       */
};

static
CHAR *rinfstgs[MAXFLD];            /* strings to store registry info       */

CHAR *regakey;                     /* key req'd to access registry agent   */

VOID                               /* NOTE: called from REGISTRY.C         */
inicsregis(VOID)                   /* initialize registry agent            */
{
     register_agent(&regagt);
     regakey=stgopt(REGAKEY);
     hook_announce(regannou);
     makrinf();
}

static VOID
makrinf(VOID)                      /* put registry info into rinfstgs[]    */
{
     INT cfld,sidx=0,didx=0,lencsr=RPFXSZ,lenques,lim;
     CHAR *csques[MAXFLD],*cslbl[MAXFLD],*csentsum,*sumlbl;

     setmem(rinfstgs,MAXFLD*sizeof(CHAR *),0);
     csentsum=stgopt(CSENTSUM);
     stpans(csentsum);
     reflow(csentsum);
     lencsr+=strlen(csentsum)+1;
     sumlbl=stgopt(SUMLBL);
     stpans(sumlbl);
     reflow(sumlbl);
     lencsr+=strlen(sumlbl)+1;
     for (cfld=0 ; cfld < numfds ; cfld++) {
          cslbl[cfld]=stgopt(fldmsg(cfld)+LBLOFF);
          stpans(cslbl[cfld]);
          reflow(cslbl[cfld]);
          csques[cfld]=stgopt(fldmsg(cfld)+CSQOFF);
          stp4cs(csques[cfld]);
          lenques=+strlen(csques[cfld])+strlen(cslbl[cfld])+XBYTPQ;
          lencsr+=lenques;
          if (lencsr > MXRINF || cfld == numfds-1) {
               if (lencsr > MXRINF) {
                    rinfstgs[sidx]=alczer(lencsr+RPFXSZ+1-lenques);
               }
               else {
                    rinfstgs[sidx]=alczer(lencsr+RPFXSZ+1);
               }
               if (sidx == 0) {
                    sprintf(rinfstgs[sidx],"%d\t%s\t%s\t",
                            numfds,csentsum,sumlbl);
               }
               lim=lencsr > MXRINF ? cfld : numfds;
               strcat(rinfstgs[sidx],spr("%d\t",lim-didx));
               for (; didx < lim ; didx++) {
                    strcat(rinfstgs[sidx],csques[didx]);
                    strcat(rinfstgs[sidx],spr("\t%d\t",reginf[didx].anssiz));
                    strcat(rinfstgs[sidx],cslbl[didx]);
                    if (didx < lim-1) {
                         strcat(rinfstgs[sidx],"\t");
                    }
               }
               lencsr=lenques;
               sidx++;
          }
     }
     for (cfld=0 ; cfld < numfds ; cfld++) {
          free(cslbl[cfld]);
          free(csques[cfld]);
     }
}

static VOID
regannou(VOID)                     /* notify C/S user to fill out registry  */
{
     dfaSetBlk(regbb);
     setmbk(regmb);
     if (haskey(regkey) && haskey(regakey)
      && *(ncdate(usaptr->usedat)) != '\0' && !dfaQueryEQ(usaptr->userid,0)
      && regnag) {
          prfmsg(CSREGPLS);
          addannom(prfbuf,"GALREG","EDIT");
     }
     else {
          addanno("");
     }
     rstmbk();
     dfaRstBlk();
}

static VOID
regread(                           /* read-dynapak handler                 */
INT direction,                     /*   read direction: 0=eq, 1=gt, -1=lt  */
struct saunam *dpknam)             /*   dynapak name to read               */
{
     CHAR *dpkstg,*uid,*dirent;
     static CHAR qtmp[PROSIZ+SUMSIZ+1];
     static struct regrec regrec;
     SHORT regkys=0;
     INT stgnum,i;
     GBOOL recxst,qryok;

     if (stdchk(regakey) && sameas(dpknam->usrid,usaptr->userid)) {
          dpkstg=cnvs2d(dpknam);
          if (sameas(dpkstg,"sau:key")) {
               if (haskey(regakey)) {
                    regkys|=HASAKY;
               }
               if (haskey(regkey)) {
                    regkys|=HASCKY;
               }
               if (haskey(viewkey)) {
                    regkys|=HASVKY;
               }
               rsp2read(dpknam,sizeof(SHORT),&regkys,shortFDA);
               return;
          }
          if (sameto("sau:inf ",dpkstg)) {
               if (direction == 0) {
                    stgnum=atoi(skpwrd(dpknam->suffix)+1);
                    if (stgnum >= 0 && stgnum < MAXFLD
                     && rinfstgs[stgnum] != NULL) {
                         rsp2read(dpknam,STGLEN,rinfstgs[stgnum],rtextFDA);
                         return;
                    }
               }
          }
          if (sameto("sau:rgt",dpkstg)) {
               uid=skpwrd(dpknam->suffix)+1;
               if (haskey(viewkey)
                   || ((sameto("sau:rgt ",dpkstg)
               && sameas(usaptr->userid,uid)))) {
                    dfaSetBlk(regbb);
                    recxst=FALSE;
                    if (sameto("sau:rgtp ",dpkstg)) {
                         recxst=dfaAcqLT(&regrec,uid,0);
                    }
                    else if (sameto("sau:rgt ",dpkstg)) {
                         recxst=dfaAcqEQ(&regrec,uid,0);
                    }
                    else if (sameto("sau:rgtn ",dpkstg)) {
                         recxst=dfaAcqGT(&regrec,uid,0);
                    }
                    if (recxst) {
                         strcpy(rsptmp,spr("%s\t",regrec.userid));
                         for (i=0 ; i < numfds ; i++) {
                              stzcpy(qtmp,regrec.profil+reginf[i].ansidx,
                                     reginf[i].anssiz+1);
                              strcat(rsptmp,qtmp);
                              strcat(rsptmp,"\t");
                         }
                         strcat(rsptmp,regrec.sumlin);
                         rsp2read(dpknam,STGLEN,rsptmp,rtextFDA);
                         return;
                    }
               }
          }
          if (sameto("sau:rqy",dpkstg)) {
               uid=skpwrd(dpknam->suffix)+1;
               if (haskey(viewkey)
                   || ((sameto("sau:rqy ",dpkstg)
               && sameas(usaptr->userid,uid)))) {
                    dfaSetBlk(regbb);
                    qryok=TRUE;
                    if (sameto("sau:rqyp ",dpkstg)) {
                         recxst=dfaQueryLT(uid,0);
                    }
                    else if (sameto("sau:rqy ",dpkstg)) {
                         recxst=dfaQueryEQ(uid,0);
                    }
                    else if (sameto("sau:rqyn ",dpkstg)) {
                         recxst=dfaQueryGT(uid,0);
                    }
                    else {
                         qryok=FALSE;
                    }
                    if (qryok) {
                         rsp2read(dpknam,sizeof(SHORT),&recxst,shortFDA);
                         return;
                    }
               }
          }
          if (sameto("sau:dir ",dpkstg)) {
               if (haskey(viewkey) && direction != 0) {
                    dfaSetBlk(regbb);
                    uid=skpwrd(dpknam->suffix)+1;
                    recxst=direction == 1 ? dfaAcqGT(&regrec,uid,0)
                                          : dfaAcqLT(&regrec,uid,0);
                    if (recxst) {
                         dirent=spr("%s\t%s",regrec.userid,regrec.sumlin);
                         *namtmp=*dpknam;
                         stzcpy(namtmp->suffix,
                                spr("dir %s",regrec.userid),SFXSIZ);
                         rsp2read(namtmp,STGLEN,dirent,rtextFDA);
                         return;
                    }
               }
          }
     }
     rejectreq();
}

static VOID
regwrite(                          /* write-dynapak handler                */
struct saunam *dpknam,             /*   dynapak name to write              */
USHORT length,                     /*   length of dynapak value            */
VOID *value)                       /*   dynapak value to write             */
{
     CHAR *dpkstg,*curfld;
     INT maxlen,i;
     static struct regrec regrec;
     static CHAR prostg[PROSIZ+SUMSIZ+1];
     GBOOL recxst=FALSE;

     if (stdchk(regakey) && sameas(dpknam->usrid,usaptr->userid)) {
          dpkstg=cnvs2d(dpknam);
          if (sameas(dpkstg,"sau:ent")) {
               if (haskey(regkey)) {
                    maxlen=numfds+SUMSIZ;
                    for (i=0 ; i < numfds ; maxlen+=reginf[i++].anssiz) {
                    }
                    if (length > 0 && length < maxlen) {
                         b2ccpy(prostg,(CHAR *)value,length+1);
                         if (itemcntd(prostg,FLDSEP) == numfds+1) {
                              setmem(&regrec,sizeof(struct regrec),0);
                              stzcpy(regrec.userid,usaptr->userid,UIDSIZ);
                              dfaSetBlk(regbb);
                              if (dfaAcqEQ(&regrec,regrec.userid,0)) {
                                   recxst=TRUE;
                                   regrec.sumlin[0]='\0';
                                   setmem(regrec.profil,PROSIZ,0);
                              }
                              for (i=0 ; i < numfds ; i++) {
                                   curfld=itemidxd(prostg,i,FLDSEP);
                                   movmem(curfld,
                           regrec.profil+reginf[i].ansidx,
                           min(strlen(curfld),
                               reginf[i].anssiz));
                              }
                              stzcpy(regrec.sumlin,itemidxd(prostg,i,FLDSEP),
                                     SUMSIZ);
                              if (recxst) {
                                   dfaUpdate(&regrec);
                              }
                              else {
                                   dfaInsert(&regrec);
                              }
                              rsp2write(TRUE,0,NULL,NULL);
                              return;
                         }
                    }
               }
          }
     }
     rejectreq();
}

static VOID
regxdone(VOID)                     /* file transfer-done handler           */
{
}

static VOID
regabort(VOID)                     /* abort-request handler                */
{
}
