/***************************************************************************
 *                                                                         *
 *   GALFILU.C                                                             *
 *                                                                         *
 *   Copyright (c) 1993-1997 Galacticomm, Inc.    All Rights Reserved.     *
 *                                                                         *
 *   File Libraries - More Utility Routines                                *
 *                                                                         *
 *                                                 - D. Pitchford  9/28/93 *
 *                                                                         *
 ***************************************************************************/
#include "gcomm.h"
#include "majorbbs.h"
#include "gcspsrv.h"
#include "fcntl.h"
#include "galfil.h"
#include "filexfer.h"
#include "fsdbbs.h"
#include "reserve.h"
#include "galfilh.h"

#define FILREV "$Revision: 17 $"

VOID
cfilmova(VOID)                     /* moving files                         */
{
     INT loop;
     struct fllib *libptr;

     if (flo->movstt) {
          movecyc();
          btuinj(usrnum,CYCLE);
          return;
     }
     if (sameas(flo->miscfil,"x")) {
          flo->retstt=OPMENU;
          prfmsg(usrptr->substt=PRESENTR);
          return;
     }
     if (flo->miscfil[0] != '\0') {
          flo->movstt=1;
          stzcpy(movflib,curlib->libname,FLNAMESZ);
          stzcpy(movtlib,flo->misclib,FLNAMESZ);
          stzcpy(movfnam,flo->miscfil,FLFILENM);
          btuinj(usrnum,CYCLE);
          strcpy(flo->miscfil,"x");
          prfmsg((flo->flags&MOVFLAG) ? FILMOVAC : FILMOVA,movtlib,movfnam);
          return;
     }
     for (loop=0 ; loop < systags ; loop++) {
          if ((ftag=tagoff(loop))->status > TGEMPTY
           && usrnum == ftag->usrnum
           && !sameas(flo->misclib,ftag->libname)) {
               libptr=libfind(ftag->libname);
               if (libptr != NULL && !(libptr->flags&FLGCBD)) {
                    flo->movstt=1;
                    stzcpy(movflib,ftag->libname,FLNAMESZ);
                    stzcpy(movtlib,flo->misclib,FLNAMESZ);
                    stzcpy(movfnam,ftag->filname,FLFILENM);
                    prfmsg((flo->flags&MOVFLAG) ? FILMOVAC : FILMOVA,movtlib,
                       movfnam);
                    prf("%s"SLS"%s\r",ftag->libname,ftag->filname);
               }
               else {
                    prf("\rCan't copy or move file from CD Library: %s"SLS
               "%s\r",ftag->libname,ftag->filname);
               }
               btuinj(usrnum,CYCLE);
               ftag->status=-ftag->status;
               return;
          }
     }
     flo->retstt=OPMENU;
     prfmsg(usrptr->substt=PRESENTR);
}

VOID
movecyc(VOID)                      /* move a file                          */
{
     static LONG pos;
     static struct key2 kwds;
     INT retval=1,loop,byte;
     CHAR *stg;
     struct fllib *libptr;

     if (sameas(movflib,movtlib)) {
          flo->movstt=0;
     }
     switch (flo->movstt) {
     case 1:                       /* redo data                            */
          dfaSetBlk(flfdat);
          if (dfaAcqEQ(NULL,compkey(movtlib,movfnam),COMPLF)) {
               prfmsg(BEEP);
               setmisc(movtlib);
               prfmsg(WARNMOVE);
               setmisc("");
               retval=0;
               break;
          }
          if (dfaAcqEQ(NULL,compkey(movflib,movfnam),COMPLF)) {
               if (!(flo->flags&MOVFLAG)) {
                    untagall(flf->libname,flf->filname);
               }
               stzcpy(flf->libname,movtlib,FLNAMESZ);
               if ((flo->flags&MOVFLAG)) {
                    dfaInsertV(NULL,FLFILREC+strlen(flf->desc)+1);
               }
               else {
                    dfaUpdateV(NULL,FLFILREC+strlen(flf->desc)+1);
               }
          }
          dfaRstBlk();
          if (!(flo->flags&MOVFLAG) && (libptr=libfind(movflib)) != NULL) {
               if (notapped(flf->udate) && (libptr->appwait > 0)) {
                    libptr->appwait--;
               }
               chuldate(libptr,flf->udate,0);
               libptr->totbytes-=flclfit(flf->siz,libptr->cluster);
               libptr->numfiles--;
               libptr->flags|=LIBONG;
          }
          if ((libptr=libfind(movtlib)) != NULL) {
               if (notapped(flf->udate)) {
                    libptr->appwait++;
               }
               libptr->totbytes+=flclfit(flf->siz,libptr->cluster);
               libptr->numfiles++;
               chuldate(libptr,flf->udate,1);
               libptr->flags|=LIBCHN;
          }
          if (!(flo->flags&MOVFLAG)) {
               flo->movstt++;
          }
          else {
               dfaSetBlk(flkdat);
               if (!longsrch
                  && dfaAcqEQ(&kwds,rcompkey(movflib,movfnam),COMPFL_K)) {
                    pos=dfaAbs();
                    flo->movstt++; /* copy keyword records */
               }
               else {
                    flo->movstt=3; /* skip keywords, there aren't any */
               }
               dfaRstBlk();
          }
          break;
     case 2:                       /* redo keywords, if any                */
          dfaSetBlk(flkdat);
          if (!(flo->flags&MOVFLAG)) { /* rename libraries */
               if (!longsrch
                  && dfaAcqEQ(&kwds,rcompkey(movflib,movfnam),COMPFL_K)) {
                    stzcpy(kwds.libkey,movtlib,FLNAMESZ);
                    dfaUpdate(&kwds);
               }
               else {
                    flo->movstt++;
               }
          }
          else { /* copy them */
               stzcpy(kwds.libkey,movtlib,FLNAMESZ);
               dfaInsert(&kwds);
               if (!dfaAcqAbs(&kwds,pos,COMPFL_K) || !dfaAcqNX(&kwds)
                  || !sameas(kwds.libkey,movflib)) {
                    flo->movstt++;
               }
               else {
                    pos=dfaAbs();
               }
          }
          dfaRstBlk();
          break;
     case 3:                       /* open file for copy                   */
          if ((libptr=libfind(movflib)) != NULL) {
               if (libptr->flags&FLGCBD) {
                    retval=0;
                    prfmsg(MAWARN);
                    break;
               }
               stg=spr("%s"SLS"%s",strlen(libptr->path) ? fixpath(libptr->path)
                 : libptr->libname,movfnam);
               if ((libptr=libfind(movtlib)) != NULL) {
                    if (libptr->flags&FLGCBD) {
                         retval=0;
                         prfmsg(MAWARN2);
                         break;
                    }
               }
               movs=fopen(stg,FOPRB);
               if (movs != NULL && libptr != NULL) {
                    stg=spr("%s"SLS"%s",libpath(libptr),movfnam);
                    if (isfile(stg)) {
                         fclose(movs);
                         movs=NULL;
                         retval=0;
                         break;
                    }
                    movd=fopen(stg,FOPWB);
                    if (movd != NULL) {
                         flo->movstt++;
                    }
                    else {
                         fclose(movs);
                         movs=NULL;
                         retval=0;
                    }
               }
               else {
                    retval=0;
               }
          }
          else {
               retval=0;
          }
          break;
     case 4:                       /* copy file                            */
          for (loop=0 ; loop < 1024 ; loop++) {
               byte=fgetc(movs);
               if (!feof(movs) && !ferror(movs) && !ferror(movd)) {
                    fputc(byte,movd);
               }
               else {
                    fclose(movs);
                    fclose(movd);
                    movs=movd=NULL;
                    flo->movstt++;
                    break;
               }
          }
          break;
     case 5:                       /* delete old file                      */
          if ((libptr=libfind(movflib)) != NULL) {
               stg=spr("%s"SLS"%s",libpath(libptr),movfnam);
               if ((libptr=libfind(movtlib)) != NULL) {
                    touch(stg,spr("%s"SLS"%s",libpath(libptr),movfnam));
               }
               if (!(flo->flags&MOVFLAG)) {
                    unlink(stg);
               }
          }
          retval=0;
          break;
     default:
          retval=0;
     }
     if (!retval) {
          flo->movstt=0;
     }
}

GBOOL
cycdelib(                          /* cycle library deletion (C/S or A/A)  */
INT *stt,                          /*   deletion state, modifies           */
CHAR *libname,                     /*   library being deleted              */
CHAR *filname)                     /*   filename being deleted             */
{                                  /*   returns whether to continue cycling*/
     INT loop;

     switch (*stt) {
     case 0:
          dfaSetBlk(flfdat);
          if (dfaAcqGT(NULL,compkey(libname,""),COMPLF)
             && sameas(libname,flf->libname)) {
               stzcpy(filname,flf->filname,FLFILENM);
               dfaDelete();
               if (!longsrch) {
                    *stt=1;
               }
          }
          else {
               *stt=2;
          }
          dfaRstBlk();
          break;
     case 1:
          dfaSetBlk(flkdat);
          if (dfaAcqEQ(NULL,rcompkey(libname,filname),COMPFL_K)) {
               dfaDelete();
          }
          else {
               *stt=0;
          }
          dfaRstBlk();
          break;
     case 2:
          dfaSetBlk(flldat);
          if (dfaAcqEQ(NULL,libname,0)) {
               dfaDelete();
               shocst(spr("LIBRARY DELETED: %s",libname),
                  "The \"%s\" Library was deleted",libname);
          }
          else {
               for (loop=0 ; loop < nterms ; loop++) {
                    if (usroff(loop)->usrcls >= SUPLON) {
                         ((struct fluson *)ptrblok(flomem,loop))->nlibaxs=-1;
                    }
               }
               return(FALSE);
          }
          dfaRstBlk();
          break;
     default:
          return(FALSE);
     }
     return(TRUE);
}

VOID
cdellib(VOID)                      /* cycle Library deletion               */
{
     if (cycdelib(&flo->miscflag,flo->misclib,flo->miscfil)) {
          spinner();
          btuinj(usrnum,CYCLE);
     }
     else {
          unprop();
          prfmsg(DELETED);
          flo->retstt=OPMENU;
          prfmsg(usrptr->substt=PRESENTR);
     }
     outprf(usrnum);
}

VOID
crencyc(VOID)                      /* cycle: renaming keywords             */
{
     if (!longsrch) {
          dfaSetBlk(flkdat);
          if (dfaAcqEQ(NULL,rcompkey(curlib->libname,flo->miscfil),COMPFL_K)) {
               stzcpy(kyd->filname,flo->destpath,FLFILENM);
               dfaUpdate(NULL);
               spinner();
               btuinj(usrnum,CYCLE);
               return;
          }
     }
     unprop();
     prf("\r");
     usrptr->substt=DELMENU;
     setmisc(spr("%d",nlibtagd()));
     prfmsg(DELMENU);
     setmisc("");
     outprf(usrnum);
}

INT
dupefile(VOID)                     /* determine if file is a duplicate     */
{
     INT retval=0;

     if (curlib->flags&FLGDOS) {
          return(0);
     }
     dfaSetBlk(flfdat);
     if (unifile && dfaAcqGE(NULL,rcompkey("",flo->miscfil),COMPFL)
                 && sameas(flo->miscfil,flf->filname)) {
          dfaRstBlk();
          retval=1;
     }
     else if (dfaAcqEQ(NULL,compkey(curlib->libname,flo->miscfil),COMPLF)) {
          flo->fsrc=fopen(spr("%s"SLS"%s",libpath(curlib),flo->miscfil),FOPRB);
          if (flo->fsrc != NULL) {
               fclose(flo->fsrc);
               flo->fsrc=NULL;
               retval=1;
          }
     }
     dfaRstBlk();
     return(retval);
}

VOID
autogone(VOID)
{
     flo->index=alwait;
     if (alwait > 0) {
          prf(getasc(AUTOGONE),alwait);
          powprf();
     }
     else {
          byenow(BANGFAST);
     }
     usrptr->substt=AUTOGONE;
     prf("");
     flo->flags&=~OFFUPLD;
}

VOID
doneLog(                           /* done with cycled autolog process     */
GBOOL prfNow)                      /*   print now or let promptin()?       */
{
     prfmsg(DONE);
     donewrit(0);
     if (flo->flags&OFFUPLD) {
          autogone();
     }
     else if (!haskey(flsysop) || !(flo->flags&RETUOPM)) {
          usrptr->substt=ENTULFIL;
     }
     else {
          flo->retstt=OPMENU;
          usrptr->substt=PRESENTR;
     }
     rstrxf();
     if (prfNow) {
          promptin();
     }
}

VOID
cautolog(VOID)                     /* cycle: logging in uploaded files     */
{
     INT edtstt;

     if (ulfileq(0) && !sameas(flo->miscfil,flmisc)) {
          stzcpy(flo->miscfil,flmisc,FLFILENM);
     }
     else {
          flo->miscfil[0]='\0';
          if (ulfileq(1)) {
               btuinj(usrnum,CYCLE);
          }
          else {
               doneLog(TRUE);
               outprf(usrnum);
          }
          return;
     }
     if (flo->dodesc == ASKDESC && !(curlib->flags&FLGDOS) && !dupefile()) {
          flo->miscfil[0]='\0';
          prfmsg(usrptr->substt=DODESC);
          outprf(usrnum);
     }
     else {
          unlink(userdir(2));
          unlink(userdir(3));
          prfmsg(AUTOLOG,flo->miscfil);
          switch (edtstt=editgo("")) {
          case 0:
               doneLog(TRUE);
               break;
          case INS_RENAME:
          case INS_BADNAME:
               stzcpy(flo->miscfil,flf->filname,FLFILENM);
               if (edtstt == INS_BADNAME) {
                    prfmsg(usrptr->substt=BADNAME);
               }
               else if (unifile && dupefile()
                     && !sameas(curlib->libname,flf->libname)) {
                    prfmsg(usrptr->substt=RENAME);
               }
               else if (ucanovw(curlib,flf)) {
                    prfmsg(usrptr->substt=RENAMO);
               }
               else {
                    prfmsg(usrptr->substt=RENAME);
               }
               break;
          case INS_DONE:
          case INS_MOVE:
               stzcpy(flo->miscfil,flf->filname,FLFILENM);
               if (flo->flags&REUPLOD) {
                    if (edtstt == INS_MOVE) {     /* copy reuploaded file */
                         flo->retstt=ENTULFIL;
                         prfmsg(usrptr->substt=COPYING);
                         outprf(usrnum);
                         btuinj(usrnum,CYCLE);
                         return;
                    }
                    donewrit(0);
                    prfmsg(usrptr->substt=ENTULFIL);
                    outprf(usrnum);
                    return;
               }
               unprop();
               outprf(usrnum);
               if (edtstt == INS_MOVE) {
                    flo->retstt=DIZZYING;
                    prfmsg(usrptr->substt=COPYING);
                    btuinj(usrnum,CYCLE);
               }
               else {
                    if (samend(flo->destpath,".ZIP") && openzip()) {
                         if (flo->retstt == SEARCHEM) {
                              flo->retstt=0;
                         }
                         prfmsg(usrptr->substt=DIZZYING);
                         btuinj(usrnum,CYCLE);
                    }
                    else {
                         flo->retstt=ENTULFIL;
                         if (longsrch || !kwdout()) {
                              donewrit(0);
                              entrdesc();
                         }
                    }
               }
               break;
          case INS_ERROR:
               prfmsg(INSERR);
               unlink(flo->srcpath);
               btuinj(usrnum,CYCLE);
               break;
          default:
               ASSERT(FALSE);
          }
          prf("");
          outprf(usrnum);
     }
}

VOID
cunapp(VOID)                       /* cycle: unapproving files             */
{
     INT cont=0;
     struct fllib *libptr;

     dfaSetBlk(flfdat);
     if (getaufil(1,1) && dfaAcqEQ(NULL,&flo->key1,COMPLF)) {
          libptr=libfind(flf->libname);
          chuldate(libptr,flf->udate,0);
          stzcpy(flf->udate,NOTAPPED,DATESZ);
          flf->utime=now();
          dfaUpdateV(NULL,FLFILREC+strlen(flf->desc)+1);
          prfmsg(UNAPPED);
          untagall(flf->libname,flf->filname);
          if (libptr != NULL) {
               libptr->appwait++;
               libptr->flags|=LIBONG;
          }
          if (getaufil(0,1)) {
               cont=1;
          }
     }
     if (cont) {
          btuinj(usrnum,CYCLE);
     }
     else {
          prfmsg(UNAPDONE);
          flo->retstt=OPMENU;
          prfmsg(usrptr->substt=PRESENTR);
     }
     outprf(usrnum);
}

VOID
capp(VOID)                         /* cycle: approving files               */
{
     struct fllib *libptr;
     INT cont=0;

     dfaSetBlk(flfdat);
     if ((flo->autol && dfaAcqGT(NULL,&flo->u.key0,COMPLUF)
        && notapped(flf->udate) && sameas(flf->libname,flo->u.key0.libname))
        || (!flo->autol && getaufil(1,0) && dfaAcqEQ(NULL,&flo->key1,COMPLF))) {
          libptr=libfind(flf->libname);
          if (flo->autol) {
               stzcpy(flo->u.key0.filname,flf->filname,FLFILENM);
          }
          if (flo->autol != 2) {
               stzcpy(flf->udate,ddat2srt(today()),DATESZ);
               chuldate(libptr,flf->udate,1);
               flf->utime=now();
               dfaUpdateV(NULL,FLFILREC+strlen(flf->desc)+1);
               prfmsg(APPED);
          }
          else {
               dfaDelete();
               untagall(flf->libname,flf->filname);
               prfmsg(DELED);
          }
          if (libptr != NULL) {
               if (libptr->numfiles > 0 && flo->autol == 2) {
                    libptr->numfiles--;
                    libptr->totbytes-=flclfit(flf->siz,libptr->cluster);
                    libptr->flags|=LIBONG;
               }
               if (libptr->appwait > 0) {
                    libptr->appwait--;
                    libptr->flags|=LIBONG;
               }
          }
          if ((!flo->autol && getaufil(0,0)) || flo->autol) {
               cont=1;
          }
     }
     if (cont) {
          btuinj(usrnum,CYCLE);
     }
     else {
          prfmsg(APDONE);
          flo->retstt=(flo->autol == 2 ? DELMENU : APPMENU);
          prfmsg(usrptr->substt=PRESENTR);
     }
     outprf(usrnum);
}

VOID
cbigcpy(VOID)                      /* cycle: copying files                 */
{
     INT loop,byte,flag=0;

     if (flo->fsrc == NULL) {
          flo->fsrc=fopen(spr("%s%s",flo->keylist,flo->fb.ff_name),FOPRB);
          flo->fdst=fopen(spr("%s"SLS"%s",userdir(1),flo->fb.ff_name),FOPWB);
          if (flo->fsrc == NULL || flo->fdst == NULL) {
               flag=1;
               prfmsg(BEEP);
               prf("[0;1;35m%s - File Error!\r\r",flo->fb.ff_name);
               if (flo->fsrc != NULL) {
                    fclose(flo->fsrc);
                    flo->fsrc=NULL;
               }
               if (flo->fdst != NULL) {
                    fclose(flo->fdst);
                    flo->fdst=NULL;
               }
          }
          else {
               prfmsg(NOWCOPY,flo->fb.ff_name,fzer(flo->fb.ff_fsize/1024L));
               flo->tot=0L;
          }
     }
     if (!flag) {
          for (loop=0 ; loop < 1024 ; loop++) {
               byte=fgetc(flo->fsrc);
               if (!feof(flo->fsrc) && !ferror(flo->fsrc) && !ferror(flo->fdst)) {
                    fputc(byte,flo->fdst);
               }
               else {
                    loop=2000;
               }
          }
     }
     if (flag || loop >= 2000) {
          if (flo->fsrc != NULL) {
               fclose(flo->fsrc);
               flo->fsrc=NULL;
          }
          if (flo->fdst != NULL) {
               fclose(flo->fdst);
               flo->fdst=NULL;
          }
          if (!flag) {
               touch(spr("%s%s",flo->keylist,flo->fb.ff_name),
                     spr("%s"SLS"%s",userdir(1),flo->fb.ff_name));
          }
          while ((flag=fndnxt(&flo->fb)) != 0 && (flo->fb.ff_attrib&FAMDIR)) {
          }
          if (!flag) {
               if (ulfileq(0)) {
                    usrptr->substt=AUTOLOG;
                    flo->dodesc=ASKDESC;
                    btuinj(usrnum,CYCLE);
                    prf("%c%c%c%c100%%\r",8,8,8,8);
                    outprf(usrnum);
                    unbreak();
                    return;
               }
               flo->retstt=OPMENU;
               prfmsg(usrptr->substt=PRESENTR);
               outprf(usrnum);
               rstrxf();
               return;
          }
          flo->tot=flo->fb.ff_fsize;
     }
     else {
          flo->tot+=1024;
     }
     if (flo->fb.ff_fsize > 0L) {
          prf("%c%c%c%c%3s%%",8,8,8,8,l2as(100L*flo->tot/flo->fb.ff_fsize));
     }
     else {
          prf("%c%c%c%c100%%",8,8,8,8);
     }
     btuinj(usrnum,CYCLE);
     prf("");
     outprf(usrnum);
}

VOID
csearch(VOID)                      /* cycle: maintenance routines          */
{
     INT cont=0;

     switch (abs(flo->miscflag)) {
     case 1:
     case 3:
          cont=srch1();
          break;
     case 2:
     case 4:
          cont=srch2();
     }
     if (cont) {
          btuinj(usrnum,CYCLE);
          return;
     }
     flo->retstt=OPMENU;
     prfmsg(usrptr->substt=PRESENTR);
     outprf(usrnum);
     rstrxf();
}

VOID
cfildel(VOID)                      /* cycle: file deletion                 */
{
     INT loop;
     struct fllib *libptr;

     switch (usrptr->substt) {
     case FILDELA:
          for (loop=0 ; loop < systags ; loop++) {
               if ((ftag=tagoff(loop))->status > TGEMPTY
             && usrnum == ftag->usrnum
             && (libptr=libfind(ftag->libname)) != NULL
             && isflop(libptr)) {
                    prfmsg(usrptr->substt);
                    dfaSetBlk(flfdat);
                    if (dfaAcqEQ(NULL,compkey(ftag->libname,ftag->filname),
                      COMPLF)) {
                         dfaDelete();
                         if (flo->flags&DELTHEM) {
                              unlink(spr("%s"SLS"%s",libpath(libptr),
                                 ftag->filname));
                         }
                    }
                    prf("%s"SLS"%s\r",ftag->libname,ftag->filname);
                    dfaRstBlk();
                    if (notapped(flf->udate)) {
                         libptr->appwait--;
                    }
                    chuldate(libptr,flf->udate,0);
                    libptr->numfiles--;
                    libptr->totbytes-=flclfit(flf->siz,libptr->cluster);
                    libptr->flags|=LIBONG;
                    stzcpy(flo->miscfil,ftag->filname,FLFILENM);
                    stzcpy(flo->misclib,ftag->libname,FLNAMESZ);
                    if (!longsrch) {
                         prfmsg(usrptr->substt=FILDELB);
                         flo->prop=0;
                    }
                    btuinj(usrnum,CYCLE);
                    outprf(usrnum);
                    untagall(flo->misclib,flo->miscfil);
                    return;
               }
          }
          flo->retstt=OPMENU;
          prfmsg(DONE);
          prfmsg(usrptr->substt=PRESENTR);
          break;
     case FILDELB:
          dfaSetBlk(flkdat);
          if (dfaAcqEQ(NULL,rcompkey(flo->misclib,flo->miscfil),COMPFL_K)) {
               dfaDelete();
               spinner();
          }
          else {
               unprop();
               usrptr->substt=FILDELA;
          }
          btuinj(usrnum,CYCLE);
          dfaRstBlk();
     }
     outprf(usrnum);
     prf("");
}

VOID
cflist(VOID)                       /* cycle: file list                     */
{
     INT cont,flag;

     cont=(!(flo->flags&STOPLST) && srcincx());
     actdet=cont;
     if (cont) {
          if (srcnext()) {
               flag=srcgood();
               if (flag == 1) {
                    srcukey();
                    srcdrec(0);
                    if (!srcincx() && flo->keymeth != 9 && !srcnext()) {
                         if (!(flo->flags&USRANSI)) {
                              unprop();
                         }
                         flo->prop=0;
                         flo->atend|=((flo->flags&REVSRCH)
                            ? LSTFORE : LSTBACK);
                         cont=0;
                    }
               }
               else if (flag == -1) {
                    srcukey();
                    if (flo->prop == 0 && (flo->flags&USRANSI)) {
                         prfmsg(SRCHIN);
                    }
                    spinner();
               }
               else {
                    if (!(flo->flags&USRANSI)) {
                         unprop();
                    }
                    flo->prop=0;
                    flo->atend|=((flo->flags&REVSRCH) ? LSTFORE : LSTBACK);
                    cont=0;
               }
          }
          else {
               if (!(flo->flags&USRANSI)) {
                    unprop();
               }
               flo->prop=0;
               flo->atend|=((flo->flags&REVSRCH) ? LSTFORE : LSTBACK);
               cont=0;
          }
     }
     if (!cont && !(flo->flags&STOPLST)) {
          flo->flags|=STOPLST;
          srcpaus(0);
     }
     prf("");
     outprf(usrnum);
     btuinj(usrnum,CYCLE);
}

VOID
entrdesc(VOID)                     /* enter a description if needed        */
{
     if (flo->dodesc == DOADESC) {
          flo->retstt=AUTOLOG;
          usrptr->substt=PRESENTR;
          flo->dodesc=ASKDESC;
          bgnfiled(0);
     }
     else {
          if (flo->dodesc != NEVRASK) {
               flo->dodesc=ASKDESC;
          }
          usrptr->substt=AUTOLOG;
          btuinj(usrnum,CYCLE);
     }
}

VOID
ccopying(VOID)                     /* cycle: copying cycle                 */
{
     INT loop,byte;
     CHAR *stg;
     struct fllib *libptr;

     if ((flo->fsrc == NULL) || (flo->fdst == NULL)) {
          return;
     }
     spinner();
     for (loop=0 ; loop < 1024 ; loop++) {
          byte=fgetc(flo->fsrc);
          if (!feof(flo->fsrc) && !ferror(flo->fsrc) && !ferror(flo->fdst)) {
               fputc(byte,flo->fdst);
          }
          else {
               loop=2000;
          }
     }
     if (loop >= 2000) {
          unprop();
          fclose(flo->fsrc);
          fclose(flo->fdst);
          touch(flo->srcpath,flo->destpath);
          unlink(flo->srcpath);
          flo->fsrc=flo->fdst=NULL;
          libptr=libfind(flo->u.key1.libname);
          if ((libptr == NULL || !(libptr->flags&FLGDOS))
           && flo->retstt == DIZZYING) {
               stg=flo->destpath;
               if (samend(stg,".ZIP") && openzip()) {
                    prfmsg(usrptr->substt=DIZZYING);
                    btuinj(usrnum,CYCLE);
               }
               else {
                    entrdesc();
               }
          }
          else {
               usrptr->substt=AUTOLOG;
               btuinj(usrnum,CYCLE);
          }
     }
     else {
          btuinj(usrnum,CYCLE);
     }
     outprf(usrnum);
}

VOID
cdizzy(VOID)                       /* cycle: manipulate zip/diz file       */
{
     spinner();
     if (dizread(vdaptr)) {
          btuinj(usrnum,CYCLE);
     }
     else {
          unprop();
          usrptr->substt=PRESENTR;
          gather();
          if (flo->retstt == SEARCHEM) {
               usrptr->substt=SEARCHEM;
               dofiler(descedit);
               btuinj(usrnum,CYCLE);
               outprf(usrnum);
               return;
          }
          dfaSetBlk(flfdat);
          setmem(flf,sizeof(struct flfile),0);
          if (dfaAcqEQ(NULL,&flo->key1,COMPLF)) {
               stzcpy(flf->desc,descedit,DESCSIZ);
               dfaUpdateV(NULL,FLFILREC+strlen(flf->desc)+1);
               if (!longsrch && kwdout()) {
                    flo->retstt=DIZZYING;
                    outprf(usrnum);
                    return;
               }
               setmem(descedit,DESCSIZ,0);
               setmem(flf,FLFILREC+DESCSIZ,0);
          }
          entrdesc();
     }
     outprf(usrnum);
}

VOID
cliblst(VOID)                      /* cycle: list libs                     */
{
     INT cont=1,loop=0;

     while (loop < 3 && cont) {
          curlib=nxtlib();
          if (curlib != NULL) {
               if (flo->retstt != SELLIB2 || isflop(curlib)) {
                    prfmsg(LIBLSTE);
                    loop++;
               }
          }
          else {
               if (flo->retstt != MMENU) {
                    usrptr->substt=flo->retstt;
                    prfmsg(SELLIB);
               }
               else {
                    retmenu(0);
                    flo->flags&=~LONGDSC;
                    usrptr->substt=MMENU;
                    injacr();
               }
               cont=0;
          }
     }
     outprf(usrnum);
     if (cont) {
          btuinj(usrnum,CYCLE);
     }

}

VOID
ckeyword(VOID)                     /* cycle: logging in kwds post-upload   */
{
     if (keywordy()) {
          btuinj(usrnum,CYCLE);
     }
     else {
          unprop();
          setmem(descedit,DESCSIZ,0);
          setmem(flf,FLFILREC+DESCSIZ,0);
          entrdesc();
     }
     prf("");
     outprf(usrnum);
}

VOID
cwldsrch(VOID)                     /* tagging wildcarded files             */
{
     INT gd,loop;
     CHAR filname[9],*path;
     struct fllib *libptr=NULL;

     spinner();
     if (flo->u.key4.libname[0] != '\0') {
          libptr=libfind(flo->u.key4.libname);
     }
     if (libptr != NULL && (libptr->flags&FLGDOS)) {
          if (flo->u.key4.filname[0] == '\0') {
               gd=fnd1st(&flo->fb,
                         spr("%s"SLS"%s",libpath(libptr),flo->miscfil),0);
          }
          else {
               gd=fndnxt(&flo->fb);
          }
          if (gd) {
               getShortName(flo->u.key4.filname
                           ,spr("%s"SLS"%s",libpath(libptr),flo->fb.ff_name)
                           ,FLFILENM);
               gd=2;
          }
     }
     else {
          gd=srcnext();
          if (gd) {
               gd=srcgood();
               srcukey();
               if ((libptr->flags&FLGCBD) || !dlfroml(libptr)) {
                    gd=-1;
               }
          }
     }
     if (flo->wtnum < 0) {
          flo->wtnum=(-flo->wtnum)-1;
          gd=0;
     }
     switch (gd) {
     case 2:
          if (flo->fsrc != NULL) {
               fprintf(flo->fsrc,"%s %s\n",flo->u.key4.libname,
                  flo->u.key4.filname);
               unprop();
               prfmsg(WTAGLN,flo->u.key4.libname,flo->u.key4.filname);
               flo->wtnum++;
               flo->wtsiz+=flo->fb.ff_fsize;
               btuinj(usrnum,CYCLE);
               break;
          }
     case 1:
          if (flo->fsrc != NULL) {
               fprintf(flo->fsrc,"%s %s\n",flf->libname,flf->filname);
               unprop();
               prfmsg(WTAGLN,flf->libname,flf->filname);
               flo->wtnum++;
               flo->wtsiz+=flf->siz;
               btuinj(usrnum,CYCLE);
               break;
          }
     case 0:
          unprop();
          if (flo->fsrc != NULL) {
               fclose(flo->fsrc);
               flo->fsrc=NULL;
          }
          if (flo->wtnum < 1) {
               prfmsg(ENDWTAGN);
               prfmsg(usrptr->substt=ENTDLFIL);
               unlink(spr("%s"SLS"temptags.%d",copydir,usrnum));
               break;
          }
          unlink(spr("%s"SLS"tagfile.%d",copydir,usrnum));
          if (!rename(spr("%s"SLS"temptags.%d",copydir,usrnum),
                spr("%s"SLS"tagfile.%d",copydir,usrnum))) {
               prfmsg(ENDWTAG,flo->wtnum,l2as(flo->wtsiz));
          }
          flo->retstt=ENTDLFIL;
          strcpy(filname,"*");
          flo->retstt=WLDSRCH;
          flo->flags&=~OFTGMAN;
          usrptr->substt=TAGMAN;
          if (!submit(curlib->libname,filname,"",DOWNLOD,0)) {
               prfmsg(ENDWTAGE);
               prfmsg(usrptr->substt=ENTDLFIL);
               unlink(spr("%s"SLS"tagfile.%d",copydir,usrnum));
          }
          else {
               prf("");
               for (loop=0 ; loop < systags ; loop++) {
                    if (ftag == tagoff(loop)) {
                         break; /* get tag# submit() used */
                    }
               }
               if (loop < systags) {
                    unlink(path=spr("%s"SLS"tags%d.fil",copydir,loop));
                    rename(spr("%s"SLS"tagfile.%d",copydir,usrnum),path);
               }
          }
          break;
     default:
          btuinj(usrnum,CYCLE);
          break;
     }
     outprf(usrnum);
     prf("");
}

VOID
cwldsys(VOID)                      /* selecting wildcarded files           */
{
     INT gd;

     spinner();
     if (flo->u.key4.libname[0] != '\0') {
          if (libfind(flo->u.key4.libname) == NULL) {
               return;
          }
     }
     gd=srcnext();
     if (gd) {
          gd=srcgood();
          srcukey();
     }
     if (flo->wtnum < 0) {
          flo->wtnum=(-flo->wtnum)-1;
          gd=0;
     }
     switch (gd) {
     case 2:
          if (flo->fsrc != NULL) {
               fprintf(flo->fsrc,"%s %s\n",flo->u.key4.libname,
                  flo->u.key4.filname);
               unprop();
               prfmsg(WTAGLN,flo->u.key4.libname,flo->u.key4.filname);
               flo->wtnum++;
               btuinj(usrnum,CYCLE);
               break;
          }
     case 1:
          if (flo->fsrc != NULL) {
               fprintf(flo->fsrc,"%s %s\n",flf->libname,flf->filname);
               unprop();
               prfmsg(WTAGLN,flf->libname,flf->filname);
               flo->wtnum++;
               btuinj(usrnum,CYCLE);
               break;
          }
     case 0:
          unprop();
          if (flo->fsrc != NULL) {
               fclose(flo->fsrc);
               flo->fsrc=NULL;
          }
          flo->fsrc=fopen(spr("%s"SLS"temptags.%d",copydir,usrnum),FOPRB);
          if (flo->fsrc == NULL || flo->wtnum < 1) {
               prfmsg(ENDWTAGN);
               prfmsg(usrptr->substt=abs(flo->retstt));
               unlink(spr("%s"SLS"temptags.%d",copydir,usrnum));
               break;
          }
          strcpy(flo->miscfil,"x"); /* necessary for MOVMENU */
          prfmsg(usrptr->substt=RESOLVE);
          btuinj(usrnum,CYCLE);
          break;
     default:
          btuinj(usrnum,CYCLE);
     }
     outprf(usrnum);
     prf("");
}

VOID
cresolve(VOID)
{
     if (flo->retstt == MOVMENU) {
          cfilmova();
          if (usrptr->substt == PRESENTR) {
               clrprf();
               usrptr->substt=RESOLVE;
               flo->retstt=MOVMENU;
          }
          else {
               prf("");
               outprf(usrnum);
               return;
          }
     }
     if (readline(flo->fsrc)) {
          inplen=strlen(input);
          parsin();
          if (margc >= 2 && (curlib=libfind(margv[0])) != NULL) {
               if (strchr(margv[1],'*') == NULL
                  && strchr(margv[1],'?') == NULL) {
                    if (flo->retstt == MOVMENU) {
                         stzcpy(flo->miscfil,margv[1],FLFILENM);
                         btuinj(usrnum,CYCLE);
                         return;
                    }
                    ienuadnm(margv[1]);
                    prf("");
                    outprf(usrnum);
                    if (usrptr->substt == flo->retstt) {
                         usrptr->substt=RESOLVE;
                    }
                    switch (usrptr->substt) {
                    case RESOLVE:
                         btuinj(usrnum,CYCLE);
                         return;
                    case INDDELK:
                         flo->flags|=WLDRSLV;
                         return;
                    }
               }
          }
     }
     fclose(flo->fsrc);
     flo->fsrc=NULL;
     rstrxf();
     usrptr->substt=abs(flo->retstt);
     promptin();
}

VOID
clstcyc(VOID)                      /* cycle file list building             */
{
     INT end=0,loop;
     CHAR *pro;

     if (srcnext()) {
          switch (srcgood()) {
          case 0:
               end=1;
               break;
          case -1:
               srcukey();
               break;
          case 1:
               srcukey();
               stzcpy(descedit,flf->desc,DESCSIZ);
               darsdesc(NDESCLN,'\r');
               setmisc(dargv[0]);
               prfmsg((flo->flags&LISTALL) ? LSTLINA : LSTLIN);
               for (loop=1 ; loop < NDESCLN ; loop++) {
                    if (dargv[loop][0] != '\0') {
                         setmisc(dargv[loop]);
                         prfmsg((flo->flags&LISTALL) ? LSTLINC : LSTLINB);
                    }
               }
               if (!(flo->flags&USRANSI) || stplist) {
                    stpans(prfbuf);
               }
               optiprf();
               strcrep(prfbuf,13,10);
               fprintf(flo->fsrc,"%s",prfbuf);
               clrprf();
          }
     }
     else {
          end=1;
     }
     if (end) {
          unprop();
          fclose(flo->fsrc);
          flo->fsrc=NULL;
          prfmsg(APDONE);
          if (ftgnew()) {
               flo->retstt=usrptr->substt;
               usrptr->substt=TAGMAN;
               ftgptr->flags=FTGABL;
               ftgptr->tshndl=tshlist;
               sprintf(ftgptr->tagspc,"%s.X%02X",((flo->flags&LISTALL)
                  ? "FILES!" : curlib->libname),channel[usrnum]);
               pro=protocol();
               if (flo->savprot[0] != '\0') {
                    pro=spr("%s",flo->savprot);
                    flo->savprot[0]='\0';
               }
               ftgsbm(strlen(pro) ? pro : "?");
               if (usrptr->state == flstt) {
                    injacr();
               }
          }
          else {
               flo->retstt=MMENU;
               prfmsg(usrptr->substt=PRESENTR);
          }
     }
     else {
          btuinj(usrnum,CYCLE);
     }
}

VOID
lssta(VOID)                        /* user status routine                  */
{
     if (status == CYCLE && usrptr->state == flstt) {
          if (btuoba(usrnum) <= (outbsz-3072)) {
               if (usrptr->substt == FILELST0 || usrptr->substt == ENTRETT) {
                    btucli(usrnum);
               }
               actdet=0;
               btuinj(usrnum,CYCLE);
          }
          else {
               setmbk(flmsg);
               fluoff(usrnum);
               curlib=setuaxs();
               setftu();
               clrprf();
               switch (usrptr->substt) {
               case INDDELK:
                    dfaSetBlk(flkdat);
                    if (!longsrch && dfaAcqEQ(NULL,rcompkey(curlib->libname,
                       flo->miscfil),COMPFL_K)) {
                         dfaDelete();
                         spinner();
                         btuinj(usrnum,CYCLE);
                    }
                    else {
                         unprop();
                         if (flo->flags&WLDRSLV) {
                              usrptr->substt=RESOLVE;
                              btuinj(usrnum,CYCLE);
                         }
                         else {
                              prfmsg(usrptr->substt=PRESENTR);
                         }
                    }
                    dfaRstBlk();
                    prf("");
                    outprf(usrnum);
                    break;
               case -1:
               case -2:
                    if (ulfileq(1)) {
                         spinner();
                         btuinj(usrnum,CYCLE);
                    }
                    else {
                         unprop();
                         outprf(usrnum);
                         prf("");
                         usrptr->substt=-2;
                         btuinj(usrnum,CRSTG);
                    }
                    break;
               case CYCIDX:
                    if (ccycidx()) {
                         spinner();
                         btuinj(usrnum,CYCLE);
                    }
                    else {
                         unprop();
                         if (flo->retstt != FILELST0) {
                              setmisc(flo->miscfil);
                              prfmsg(usrptr->substt=flo->retstt);
                              setmisc("");
                              btuinj(usrnum,CYCLE);
                         }
                         else {
                              gosearch();
                         }
                    }
                    prf("");
                    outprf(usrnum);
                    prf("");
                    break;
               case ENTRETT:
                    cycinp();
               case VIEWASC:
                    if (usrptr->state == flstt) {
                         btuinj(usrnum,CYCLE);
                    }
                    break;
               case TAGSTAT:
                    cdsptags();
                    break;
               case LSTCYC:
                    spinner();
                    clstcyc();
                    prf("");
                    outprf(usrnum);
                    break;
               case WLDSRCH:
                    cwldsrch();
                    break;
               case WLDSYS:
                    cwldsys();
                    break;
               case RESOLVE:
                    cresolve();
                    break;
               case FILHELP:
               case POPWIN1:
               case POPWIN2:
               case POPWIN3:
               case POPWIN4:
               case POPWIN5:
               case POPWIN6:
               case POPWIN7:
                    cycinp();
                    btuinj(usrnum,CYCLE);
                    break;
               case SEARCHEM:
                    if (kwaut) {
                         btuinj(usrnum,CYCLE);
                    }
                    else {
                         csearch();
                    }
                    break;
               case FILDELA:
               case FILDELB:
                    cfildel();
                    break;
               case FILELST0:
                    cycinp();
                    if (usrptr->state == flstt) {
                         if (usrptr->substt != FILELST0) {
                              btuinj(usrnum,CYCLE);
                              break;
                         }
                    }
                    else {
                         break;
                    }
               case FILELST2:
               case FILELST1:
                    cflist();
                    break;
               case LIBLST:
                    cliblst();
                    break;
               case COPYING:
                    ccopying();
                    break;
               case KEYWORDY:
                    ckeyword();
                    break;
               case DIZZYING:
                    cdizzy();
                    break;
               case FILMOVA:
                    cfilmova();
                    prf("");
                    outprf(usrnum);
                    if (usrptr->substt != FILMOVA) {
                         rstrxf();
                    }
                    break;
               case BIGCPY:
                    cbigcpy();
                    break;
               case RENCYC:
                    crencyc();
                    break;
               case DELLIB:
                    cdellib();
                    break;
               case AUTOLOG:
                    cautolog();
                    break;
               case UNAPPING:
                    cunapp();
                    break;
               case APPING:
                    capp();
                    break;
               }
               clrprf();
          }
          return;
     }
     else if (status == OUTMT && usrptr->state == flstt) {
          statstrt();
          return;
     }
     dfsthn();
}

VOID
flagit(                            /* decode binary flag bits              */
INT fldspec,
LONG flag)
{
     CHAR yn[4];

     fsdfxt(fldspec,yn,4);
     libedt->lib.flags=(sameas(yn,"NO") ? libedt->lib.flags&~flag : libedt->lib.flags|flag);
}

CHAR *
dprfm(                             /* strips first flmisc in msgno         */
INT msgno)
{
     CHAR *msg,*cr;

     msg=rawmsg(msgno);
     if (flmisc[0] == '\0') {
          if (strsrep(msg,"FL_MISC","")) {
               if ((cr=strchr(msg,'')) != NULL) {
                    cr-=3;
                    strcpy(cr,&cr[4]);
               }
          }
     }
     return(xlttxv(msg,2048));
}

VOID
srcdrec(                           /* display line for searching           */
INT redisplay)
{
     INT loop,idx;
     struct key0 *key;

     if (!redisplay) {
          idx=srcincx();
          flo->tagk='A'-1+idx;
     }
     else {
          flo->tagk++;
     }
     if (!redisplay && idx == ((flo->flags&REVSRCH) ? NLISTER : 1)) {
          for (loop=0 ; loop < NLISTER ; loop++) {
               flo->tdline[loop]=0;
          }
     }
     key=&flo->tags[flo->tagk-'A'];
     if (flo->keymeth != 9) {
          stzcpy(key->filname,flf->filname,FLFILENM);
          stzcpy(key->libname,flf->libname,FLNAMESZ);
          stzcpy(key->udate,flf->udate,DATESZ);
          stzcpy(descedit,flf->desc,DESCSIZ);
          darsdesc(NDESCLN,'\r');
          setmisc(dargv[0]);
          while ( dargc > 0 && dargv[dargc-1][0] == '\0') {
               dargc--;
          }
          unprop();
     }
     loop=flo->tagk-'A';
     prf("[%df[K",flo->tagk-'A'+4);
     switch (flo->keymeth) {
     case 0:
          prf(dprfm(LISTLN0));
          break;
     case 1:
     case 6:
          prf(dprfm(LISTLN1));
          break;
     case 2:
          prf(dprfm(LISTLN2));
          break;
     case 3:
          prf(dprfm(LISTLN3));
          break;
     case 4:
     case 7:
          prf(dprfm(LISTLN4));
          break;
     case 5:
          prf(dprfm(LISTLN5));
          break;
     case 8:
          prf(dprfm(LISTLN6));
          break;
     case 9:
          if (redisplay) {
               stzcpy(flo->u.key6.filname,flo->tags[loop].filname,FLFILENM);
          }
          else {
               stlcpy(key->filname,flo->u.key6.filname,FLFILENM);
               stzcpy(key->libname,curlib->libname,FLNAMESZ);
          }
          prfmsg(LISTLN7,flo->u.key6.filname,l2as(flo->u.key6.size[loop]),
                 ncdate(flo->u.key6.date[loop]),nctime(flo->u.key6.time[loop]));
     }
     setmisc("");
     if (!redisplay) {
          flo->tdline[loop]=loop+1;
     }
     if (alrtag(flo->tags[loop].libname,flo->tags[loop].filname)
        || flo->tdline[loop] < 0) {
          flo->tdline[loop]=-abs(flo->tdline[loop]);
          if (flo->flags&USRANSI) {
               prfmsg(TAGGED,(-flo->tdline[loop])+3,'A'+loop);
          }
     }
     if (flo->cursor == loop) {
          dcurs(0);
     }
     optiprf();
}

VOID
unprop(VOID)                       /* backspace over propellor             */
{
     if (flo->prop != 0) {
          prf("");
     }
     flo->prop=0;
}

VOID
srcinit(                           /* initialize file search/list          */
INT mode,
CHAR *lib)
{
     struct fllib *libptr=NULL;

     btutsw(usrnum,0);
     setmem(&flo->u,sizeof(union combo),0);
     if (mode > 6) {
          mode-=6;
     }
     flo->keymeth=0;
     if (lib[0] != '\0') {
          libptr=libfind(lib);
     }
     if (libptr != NULL && mode == -1) {
          mode=13;
     }
     else if (lib[0] != '\0') {
          if (libptr != NULL) {
               if (scanlib(1,libptr)) {
                    mode+=6;
               }
               scanlib(0,libptr);
          }
          else {
               lib="";
               mode+=6;
          }
     }
     else {
          mode+=6;
     }
     if ((mode == 1 || mode == 7) && (flo->flags&DATESRC)) {
          stzcpy(flu->newdate,ddat2srt(today()),DATESZ);
     }
     switch (mode) {
     case 1:
          flo->keymeth=0;
          stzcpy(flo->u.key0.libname,lib,FLNAMESZ);
          if (!isflop(libptr)) {
               stzcpy(flo->u.key0.udate,"0000009",DATESZ);
          }
          break;
     case 2:
          flo->keymeth=1;
          stzcpy(flo->u.key1.libname,lib,FLNAMESZ);
          stzcpy(flo->u.key1.filname,flo->miscfil,FLFILENM);
          break;
     case 3:
     case 9:
          flo->keymeth=2;
          stzcpy(flo->u.key2.libname,lib,FLNAMESZ);
          stzcpy(flo->u.key2.keyword,vdaptr,FLKEYSIZ);
          stzcpy(flo->u.key2.origkey,vdaptr,FLKEYSIZ);
          break;
     case 4:
          flo->keymeth=4;
          stzcpy(flo->u.key4.libname,lib,FLNAMESZ);
          break;
     case 7:
          flo->keymeth=3;
          stzcpy(flo->u.key3.libname,lib,FLNAMESZ);
          if (!haskey(flsysop) && ((libptr == NULL) || !isflop(libptr))) {
               stzcpy(flo->u.key3.udate,"0000009",DATESZ);
          }
          break;
     case 8:
          flo->keymeth=(flo->styp == 8) ? 8 : 4;
          stzcpy(flo->u.key4.libname,lib,FLNAMESZ);
          stzcpy(flo->u.key4.filname,flo->miscfil,FLFILENM);
          if (flo->keymeth == 8) {
               stzcpy(flo->u.key4.exactfn,flo->miscfil,FLFILENM);
          }
          break;
     case 10:
          flo->keymeth=4;
          stzcpy(flo->u.key4.libname,lib,FLNAMESZ);
          break;
     case 5:
     case 11:
          flo->keymeth=5;
          stzcpy(flo->u.key5.numdls,"A000000",NUMSZ);
          setmem(flo->u.key5.libkey,FLNAMESZ,0);
          setmem(flo->u.key5.filname,FLFILENM,0);
          stzcpy(flo->u.key5.libname,lib,FLNAMESZ);
          break;
     case 6:
          flo->keymeth=6;
          stzcpy(flo->u.key1.libname,lib,FLNAMESZ);
          wldstuff(flo->u.key1.filname);
          break;
     case 12:
          flo->keymeth=7;
          stzcpy(flo->u.key4.libname,lib,FLNAMESZ);
          wldstuff(flo->u.key4.filname);
          break;
     case 13:
          wipetag();
          flo->keymeth=9;
          flo->styp=-1;
          sprintf(flo->srcpath,"%s"SLS STAR,libpath(libptr));
     }
     switch (flo->keymeth) {
     case 0:
          stzcpy(flo->lrange,flo->u.key0.libname,FLNAMESZ);
          break;
     case 1:
     case 6:
          stzcpy(flo->lrange,flo->u.key1.libname,FLNAMESZ);
          break;
     case 2:
          stzcpy(flo->lrange,flo->u.key2.libname,FLNAMESZ);
          break;
     case 3:
          stzcpy(flo->lrange,flo->u.key3.libname,FLNAMESZ);
          break;
     case 4:
     case 7:
     case 8:
          stzcpy(flo->lrange,flo->u.key4.libname,FLNAMESZ);
          break;
     case 5:
          stzcpy(flo->lrange,flo->u.key5.libname,FLNAMESZ);
          break;
     case 9:
          stzcpy(flo->lrange,curlib->libname,FLNAMESZ);
          break;
     }
     if (initsrc()) {
          flo->retstt=FILELST0;
          prfmsg(usrptr->substt=CYCIDX);
          btuinj(usrnum,CYCLE);
     }
     else {
          gosearch();
     }
}

CHAR *
wldstuff(             /* place starting characters in key     */
CHAR *stg)
{
     CHAR *sptr,*kptr;

     setmem(kptr=stg,FLFILENM,0);
     fnmcse(sptr=flo->miscfil);
     while (1) {
          switch (*sptr) {
          case '\0':
          case '*':
          case '?':
          case '.':
               return(stg);
          }
          *kptr++=*sptr++;
     }
}

VOID
srcpaus(                           /* pause in file search, screen full    */
INT rebuild)
{
     if (flo->flags&USRANSI) {
          switch (flo->atend) {
          case LSTFILS:
               dcurs(0);
               prfmsg(LISTPAUS);
               doalr();
               break;
          case LSTBACK:
               dcurs(0);
               prfmsg(BOTLIST);
               doalr();
               if (flo->tagk == 'A'-1 && !rebuild) {
                    flo->flags|=REVSRCH;
                    flo->flags|=NXTEQUL;
                    flo->flags&=~STOPLST;
               }
               break;
          case LSTFORE:
               dcurs(0);
               if (flo->keymeth == 9) {
                    prfmsg(DOSLIST);
               }
               else {
                    prfmsg(TOPLIST);
                    if (flo->tagk == 'A'-1 && !rebuild) {
                         flo->flags&=~REVSRCH;
                         flo->flags|=NXTEQUL;
                         flo->flags&=~STOPLST;
                    }
               }
               doalr();
               break;
          case LSTONLY:
               if (flo->tagk != 'A'-1) {
                    dcurs(0);
                    prfmsg(ENDLIST);
                    doalr();
                    break;
               }
               flo->atend=LSTNONE;
          case LSTNONE:
               prfmsg(usrptr->substt=POPWIN6);
               deresume();
          }
          if (totags != 0) {
               prfmsg(CTRLT);
          }
          else {
               prfmsg(CLRCTRLT);
          }
     }
     else {
          switch (flo->atend) {
          case LSTFILS:
          case LSTFORE:
               prfmsg(LISTPAUX);
               break;
          case LSTBACK:
          case LSTONLY:
               if (flo->atend == LSTBACK || flo->tagk != 'A'-1) {
                    prfmsg(ENDLISTX);
                    break;
               }
               flo->atend=LSTNONE;
          case LSTNONE:
               prfmsg(NOFILES);
               usrptr->substt=PRESENTR;
               flo->retstt=MMENU;
               deresume();
          }
     }
}

VOID
srcukey(VOID)                      /* update keys now for file search      */
{
     INT idx;
     CHAR tempPath[GCMAXPTH];

     switch (flo->keymeth) {
     case 0:
          stzcpy(flo->u.key0.filname,flf->filname,FLFILENM);
          stzcpy(flo->u.key0.udate,flf->udate,DATESZ);
          break;
     case 1:
     case 6:
          stzcpy(flo->u.key1.filname,flf->filname,FLFILENM);
          stzcpy(flo->u.key1.libname,flf->libname,FLNAMESZ);
          break;
     case 2:
          stzcpy(flo->u.key2.keyword,kyd->keyword,FLKEYSIZ);
          stzcpy(flo->u.key2.filname,kyd->filname,FLFILENM);
          stzcpy(flo->u.key2.libkey,kyd->libkey,FLNAMESZ);
          break;
     case 3:
          stzcpy(flo->u.key3.filname,flf->filname,FLFILENM);
          stzcpy(flo->u.key3.udate,flf->udate,DATESZ);
          stzcpy(flo->u.key3.libkey,flf->libname,FLNAMESZ);
          break;
     case 4:
     case 7:
     case 8:
          stzcpy(flo->u.key4.filname,flf->filname,FLFILENM);
          stzcpy(flo->u.key4.libkey,flf->libname,FLNAMESZ);
          break;
     case 5:
          stzcpy(flo->u.key5.numdls,flf->numdls,NUMSZ);
          stzcpy(flo->u.key5.filname,flf->filname,FLFILENM);
          stzcpy(flo->u.key5.libkey,flf->libname,FLNAMESZ);
          break;
     case 9:
          idx=flo->tagk-'A'+1;
          if (curlib == NULL) {
               return;
          }
          makePath(tempPath,libpath(curlib),flo->fb.ff_name,GCMAXPTH);
          getShortName(flo->u.key6.filname,tempPath,FLFILENM);
          flo->u.key6.date[idx]=flo->fb.ff_fdate;
          flo->u.key6.time[idx]=flo->fb.ff_ftime;
          flo->u.key6.size[idx]=flo->fb.ff_fsize;
          break;
     }
}

VOID
gosearch(VOID)                     /* begin a list/search                  */
{
     unbreak();
     if (isansiu()) {
          flo->flags|=USRANSI;
     }
     else {
          flo->flags&=~USRANSI;
     }
     cncall();
     dispfhdr(1);
     flo->retstt=MMENU;
     flo->tagk='A'-1;
     flo->flags&=~REVSRCH;
     flo->flags&=~STOPLST;
     flo->cursor=0;
     flo->flags&=~DBLCLCK;
     if ((flo->keymeth == 1 && flo->u.key1.filname[0] != '\0')
      || (flo->keymeth == 4 && flo->u.key4.filname[0] != '\0')) {
          flo->atend=LSTFILS;
     }
     else {
          flo->atend=LSTFORE;
     }
     btuinj(usrnum,CYCLE);
     setbusy();
     if (flo->flags&USRANSI) {
          btutrg(usrnum,255);
     }
}

INT
libeditv(                          /* verify FSD edit Library session      */
INT fldno,
CHAR *answer)
{
     LONG lrange;
     CHAR *stg;

     switch (fldno) {
     case FLDCBD:
          if (sameas(answer,"YES")) {
               fsdfxt(FLDPATH,stg=spr(""),PATHSIZE);
               if (stg[0] == '\0') {
                    setmbk(flmsg);
                    stzcpy(fsdemg,getmsg(SVRNOT),MAXHLP);
                    rstmbk();
               }
          }
          break;
     case FLDPATH:
          if (answer[0] != '\0' && !valpath(answer)) {
               setmbk(flmsg);
               stzcpy(fsdemg,getmsg(BADDIR),MAXHLP);
               rstmbk();
               return(VFYREJ);
          }
          fnmcse(checkdir(answer));
          break;
     case FLDPLOP:
          if (answer[0] == '\0') {
               break;
          }
          if (sameas(answer,"Sysop")) {
               stzcpy(answer,"Sysop",UIDSIZ);
               break;
          }
          dfaSetBlk(accbb);
          if (!dfaAcqEQ(&acctmp,answer,0)) {
               setmbk(flmsg);
               stzcpy(fsdemg,getmsg(BADUID),MAXHLP);
               rstmbk();
               dfaRstBlk();
               return(VFYREJ);
          }
          else {
               stzcpy(answer,acctmp.userid,UIDSIZ);
          }
          dfaRstBlk();
          break;
     case FLDVIS:
     case FLDDLD:
     case FLDULD:
     case FLDOVW:
     case FLDAPU:
     case FLDLOP:
          if (answer[0] != '\0' && !keynam(strupr(answer))) {
               setmbk(flmsg);
               stzcpy(fsdemg,getmsg(BADKEY),MAXHLP);
               rstmbk();
               return(VFYREJ);
          }
          break;
     case FLDROY:
          if ((lrange=atol(answer)) < 0L || lrange > 100L) {
               setmbk(flmsg);
               stzcpy(fsdemg,getmsg(BADROY),MAXHLP);
               rstmbk();
               return(VFYREJ);
          }
          strcpy(answer,l2as(lrange));
          break;
     case FLDMFL:
     case FLDMBT:
     case FLDMUP:
          if ((lrange=atol(answer)) < 0L || lrange > 999999999L) {
               setmbk(flmsg);
               stzcpy(fsdemg,getmsg(BADLONG),MAXHLP);
               rstmbk();
               return(VFYREJ);
          }
     case FLDCDF:
     case FLDCDK:
          strcpy(answer,l2as(atol(answer)));
     }
     return(vfyadn(fldno,answer));
}

VOID
libeditd(                          /* finish editing Library area          */
SHORT save)
{
     CHAR lng[10];
     INT loop;

     flu=&fluarr[usrnum];
     if (flu->lib[0] == '\0') {
          return;
     }
     setmbk(flmsg);
     curusr(usrnum);
     fluoff(usrnum);
     flo->flags&=~ISEDLIB;
     usrptr->state=flstt;
     usrptr->substt=OPMENU;
     if ((fsdscb->chgcnt == 0) && (libfind(libedt->lib.libname) != NULL)) {
          prfmsg(NOCH);
          setmem(libedt,sizeof(struct libdisk),0);
     }
     else if (!save || (libedt->lib.libname[1] == '')) {
          prfmsg(CHQUIT);
          setmem(libedt,sizeof(struct libdisk),0);
     }
     else {
          if (libedt->lib.libname[0] == '\0') {
               fsdfxt(FLDNAME,libedt->lib.libname,FLNAMESZ);
          }
          fsdfxt(FLDDESC,libedt->lib.libdesc,FLDESCSZ);
          if (sameas(libedt->lib.libdesc,DESCSNON)) {
               setmem(libedt->lib.libdesc,FLDESCSZ,0);
          }
          fsdfxt(FLDDESC4,libedt->ldesc[4],FLLDESCS);
          fsdfxt(FLDDESC3,libedt->ldesc[3],FLLDESCS);
          fsdfxt(FLDDESC2,libedt->ldesc[2],FLLDESCS);
          fsdfxt(FLDDESC1,libedt->ldesc[1],FLLDESCS);
          fsdfxt(FLDDESC0,libedt->ldesc[0],FLLDESCS);
          if (sameas(libedt->ldesc[0],DESCLNON)) {
               setmem(libedt->ldesc[0],FLDESCSZ,0);
          }
          for (loop=(NLDLIN-2) ; loop >= 0 ; loop--) {
               if (libedt->ldesc[loop][0] == '\0') {
                    movmem(libedt->ldesc[loop+1],libedt->ldesc[loop],
                       FLLDESCS*(NLDLIN-1-loop));
                    libedt->ldesc[NLDLIN-1][0]='\0';
               }
          }
          fsdfxt(FLDPATH,libedt->lib.path,PATHSIZE);
          fsdfxt(FLDPLOP,libedt->lib.primary,UIDSIZ);
          flagit(FLDHID,FLGHID);
          flagit(FLDCBD,FLGCBD);
          flagit(FLDRDO,FLGRDO);
          flagit(FLDAUL,FLGAUL);
          flagit(FLDADL,FLGADL);
          flagit(FLDFDL,FLGFDL);
          flagit(FLDFUL,FLGFUL);
          fsdfxt(FLDCDF,lng,10);
          libedt->lib.dlchge=atol(lng);
          fsdfxt(FLDCDK,lng,10);
          libedt->lib.kdlchge=atol(lng);
          fsdfxt(FLDROY,lng,10);
          libedt->lib.royal=atoi(lng);
          fsdfxt(FLDMFL,lng,10);
          libedt->lib.maxfil=atol(lng);
          fsdfxt(FLDMBT,lng,10);
          libedt->lib.maxbyt=atol(lng);
          fsdfxt(FLDMUP,lng,10);
          libedt->lib.maxbup=atol(lng);
          fsdfxt(FLDVIS,libedt->lib.keyreq,KEYSIZ);
          fsdfxt(FLDDLD,libedt->lib.dlkey,KEYSIZ);
          fsdfxt(FLDULD,libedt->lib.ulkey,KEYSIZ);
          fsdfxt(FLDOVW,libedt->lib.overw,KEYSIZ);
          fsdfxt(FLDAPU,libedt->lib.autoap,KEYSIZ);
          fsdfxt(FLDLOP,libedt->lib.libop,KEYSIZ);
          if (savelib(libedt)) {
               prfmsg(SAVADDED);
          }
          else {
               prfmsg(SAVED);
          }
          setmem(libedt,sizeof(struct libdisk),0);
          fluoff(usrnum);
          stzcpy(flu->lib,libedt->lib.libname,FLNAMESZ);
          curlib=setuaxs();
     }
     btucli(usrnum);
     fluoff(usrnum);
     promptin();
     clrprf();
}

GBOOL
savelib(                           /* save/create Library (C/S generic)    */
struct libdisk *sav)               /*   library data to save               */
{                                  /*   ret TRUE if created, FALSE if saved*/
     struct fllib *libptr;
     GBOOL retval=FALSE;
     INT loop;

     if ((libptr=libfind(sav->lib.libname)) == NULL) {
          libptr=liboff(numoflib++);
     }
     MKDIR(strupr(sav->lib.libname));
     if (sav->lib.path[0] != '\0') {
          MKDIR(sav->lib.path);
     }
     sav->lib.cluster=clsize(libpath(&sav->lib));
     movmem(&sav->lib,libptr,sizeof(struct fllib));
     dfaSetBlk(flldat);
     if (dfaAcqEQ(NULL,libptr->libname,0)) {
          dfaUpdate(sav);
     }
     else {
          dfaInsert(sav);
          shocst(spr("LIBRARY CREATED: %s",libptr->libname),
           "The \"%s\" Library was created",libptr->libname);
          retval=TRUE;
          sortlibs();
          scanlibs();
     }
     for (loop=0 ; loop < nterms ; loop++) {
          if (usroff(loop)->usrcls >= SUPLON) {
               ((struct fluson *)ptrblok(flomem,loop))->nlibaxs=-1;
          }
     }
     dfaRstBlk();
     return(retval);
}

VOID
libeditp(                         /* FSD utility function                 */
INT msgno,
INT amode)
{
     CHAR *y="YES",*n="NO";

     fsdroom(msgno,libedits,amode);
     sprintf(vdatmp,libeditf,
             ncdatel(libedt->lib.day),'\0',
             nctime(libedt->lib.time),'\0',
             libedt->lib.libname,'\0',
             libedt->lib.flags&FLGDOS ? "(OS-ONLY)" : "",'\0',
             libedt->lib.libdesc[0] != '\0' ? libedt->lib.libdesc
                                            : DESCSNON,'\0',
             libedt->ldesc[0][0] != '\0' ? libedt->ldesc[0] : DESCLNON,'\0',
             libedt->ldesc[1],'\0',
             libedt->ldesc[2],'\0',
             libedt->ldesc[3],'\0',
             libedt->ldesc[4],'\0',
             libedt->lib.path,'\0',
             libedt->lib.flags&FLGHID ? y : n,'\0',
             libedt->lib.flags&FLGCBD ? y : n,'\0',
             libedt->lib.flags&FLGRDO ? y : n,'\0',
             auditall || libedt->lib.flags&FLGAUL ? y : n,'\0',
             auditall || libedt->lib.flags&FLGADL ? y : n,'\0',
             freeuls || libedt->lib.flags&FLGFUL ? y : n,'\0',
             libedt->lib.flags&FLGFDL ? y : n,'\0',
             libedt->lib.dlchge,'\0',
             libedt->lib.kdlchge,'\0',
             libedt->lib.royal,'\0',
             libedt->lib.maxfil,'\0',
             libedt->lib.maxbyt,'\0',
             libedt->lib.maxbup,'\0',
             libedt->lib.keyreq,'\0',
             libedt->lib.dlkey,'\0',
             libedt->lib.ulkey,'\0',
             libedt->lib.overw,'\0',
             libedt->lib.autoap,'\0',
             libedt->lib.libop,'\0',
             libedt->lib.primary,'\0');
     fsdapr(vdaptr,vdasiz,vdatmp);
}

VOID
libkick(VOID)                      /* tag handler rtkick                   */
{
     INT loop,loop2,numftg,csu;
     struct user *uptr;
     static GBOOL gotjoin=FALSE;

     if (newjoins) {
          if (gotjoin) {
               sendjoin();
               gotjoin=FALSE;
               newjoins=FALSE;
          }
          else {
               gotjoin=TRUE;
          }
     }
     else {
          gotjoin=FALSE;
     }
     while (findbest(TGOTHER) != 0 && time(NULL)-ftag->tagtime > 60) {
          ftag->status=-ftag->status;
     }
     moploop();
     for (loop=0 ; loop < systags ; loop++) {
          if ((ftag=tagoff(loop))->status > TGEMPTY) {
               if (ftag->usrnum >= 0 && ftag->usrnum < nterms
                && usroff(ftag->usrnum)->usrcls >= SUPLON) {
                    usrnum=ftag->usrnum;
                    fluoff(usrnum);
                    ftag->status=-ftag->status;
                    setftu();
                    if ((numftg=ftuptr->numftg) == maxtags) {
                         numftg--;
                    }
                    for (loop2=0 ; loop2 <= numftg ; loop2++) {
                         ftgptr=&ftgusr[loop2];
                         if (ftag == spc) {
                              if (loop2 != ftuptr->numftg
                                 || flstt != usroff(usrnum)->state) {
                                   ftag->status=-ftag->status;
                                   break;
                              }
                         }
                    }
                    if (ftag->status < TGEMPTY) {
                         for (loop2=0 ; loop2 < ftuptr->savetags ; loop2++) {
                              ftgptr=&ftgusr[maxtags-loop2-1];
                              if (ftag == spc) {
                                   ftag->status=-ftag->status;
                                   break;
                              }
                         }
                    }
               }
               else {
                    ftag->status=-ftag->status;
               }
          }
     }
     if (findbest(TGCOPY) == 0) {
          if (cdst != NULL) {
               fclose(cdst);
               cdst=NULL;
          }
          if (csrc != NULL) {
               fclose(csrc);
               csrc=NULL;
          }
          if ((csu=findbest(TGINWAIT)) != 0) {
               if (ftag == NULL) { /* c/s tag */
                    lcsarr[csu-1].status=CDCOPY;
               }
               else {
                    ftag->status=TGCOPY;
               }
               initask(copyaut);
          }
     }
     libchg();
     if (!longsrch && !kwaut && kwbuf[0].keyword[0] != '\0') {
          initask(keywdaut);
          kwaut=1;
     }
     for (loop=0 ; loop < nterms ; loop++) {
          uptr=usroff(loop);
          if (uptr->usrcls > SUPIPG && uptr->state == flstt
             && uptr->substt == AUTOGONE && !(uptr->flags&BYEBYE)) {
               curusr(loop);
               fluoff(usrnum);
               setmbk(flmsg);
               if (flo->index > 0) {
                    if (flo->index >= 3) {
                         flo->index-=3;
                    }
                    else {
                         flo->index=0;
                    }
                    prfmsg(BEEP);
                    outprf(usrnum);
               }
               else {
                    byenow(BANGNOW);
               }
          }
     }
     rtkick(3,libkick);
}

VOID
prfopt(                            /* output potentially built RIP button  */
INT optno,
INT tot,
INT ctr)
{
     CHAR *msg,*stg,fntsty[RFNTSZ+1],butsty[RBSYSZ+1];
     INT len,loop;

     msg=stg=getmsg(optno);
     if (!isripu()) {
          prf("%s",msg);
          return;
     }
     strcpy(fntsty,"|Y00000100");
     strcpy(butsty,"|1B770F0207QQ020E000F080700000F07000077");
     len=strlen(stg);
     for (loop=0 ; loop < len && strncmp(stg,RIP_BUTTON,BCSIZ) != 0
        ; loop++,stg++) {
          if (strncmp(stg,RIP_FONT_STYLE,FSSIZ) == 0) {
               stzcpy(fntsty,stg,RFNTSZ+1);
          }
          else if (strncmp(stg,RIP_BUTTON_STYLE,BSSIZ) == 0) {
               stzcpy(butsty,stg,RBSYSZ+1);
          }
     }
     if (strncmp(stg,RIP_BUTTON,BCSIZ) == 0) {
          for (loop=0 ; loop < 8 ; loop++) {
               stg[3+loop]=autscns[tot-1][ctr][3+loop];
          }
          prf("\r!%s%s\r!%s",fntsty,butsty,stg);
     }
     else {
          prf("%s",msg);
     }
}

VOID
prfups(VOID)                       /* sets flmisc to report newest files   */
{
     INT loop,day,week;

     week=day=curlib->newfiles[0];
     for (loop=1 ; loop < ULDAYS ; loop++) {
          week+=curlib->newfiles[loop];
     }
     if (week != 0) {
          if (week == day) {
               prfmsg(day == 1 ? FLNFDAY : FLNFDAYS,day);
          }
          else {
               if (day == 0) {
                    prfmsg(week == 1 ? FLNFWK : FLNFWKS,week);
               }
               else {
                    prfmsg(day == 1 ? FLNFDWK : FLNFDWKS,day,week);
               }
          }
     }
}

VOID
mainmenu(VOID)                     /* display main File Libraries menu     */
{
     INT riptot,ripctr=0;
     CHAR *nfiles;

     if (curlib == NULL) {
          usrptr->substt=MMENU;
          return;
     }
     if (flo->flags&LONGDSC) {
          setmisc("");
          prfmsg(FLMMNULD);
          prfups();
          if (*(tvdesc0()) != '\0') {
               if (!isripu()) {
                    prf("\r");
               }
               prfmsg(FLMMNULC);
               prfmsg(FLMMNULT);
          }
          setmisc("");
          flo->flags&=~LONGDSC;
     }
     else {
          prfmsg(FLMMNU);
     }
     if (!(curlib->flags&FLGDOS)) {
          nfiles=tvfnum();
          switch (atoi(nfiles)) {
          case 0:
               prfmsg(FLMMNUA0);
               break;
          case 1:
               prfmsg(FLMMNUA1);
               break;
          default:
               prfmsg(FLMMNUA2,nfiles);
          }
     }
     riptot=2;
     if (flo->tagk >= 'A'
        && flo->styp != 4 && flo->styp != 6 && flo->styp != -1) {
          riptot++;
     }
     if (dlfroml(curlib)) {
          riptot++;
     }
     if (ftuptr->numftg > 0) {
          riptot++;
     }
     if (haslibkey(curlib,curlib->ulkey) && writable(curlib)) {
          riptot++;
     }
     if (flo->nlibaxs > 1) {
          riptot++;
     }
     if (isflop(curlib)) {
          riptot++;
     }
     if (haskey(listkey) && !(curlib->flags&FLGDOS)) {
          riptot++;
     }
     if (!isripu()) {
          prf("\r");
     }
     prfopt(((curlib->flags&FLGDOS) ? FLMMNUFD : FLMMNUF),riptot,ripctr++);
     if (flo->tagk >= 'A') {
          if ((flo->styp == 4) || (flo->styp == 6) || flo->styp == -1) {
               setmem(flo->u.key0.libname,FLNAMESZ,0);
          }
          else {
               prfopt(FLMMNUR,riptot,ripctr++);
          }
     }
     if (dlfroml(curlib)) {
          prfopt(FLMMNUD,riptot,ripctr++);
     }
     if (ftuptr->numftg > 0) {
          setmisc(spr("%d",ftuptr->numftg));
          prfopt(FLMMNUT,riptot,ripctr++);
          setmisc("");
     }
     if (haskey(curlib->ulkey) && writable(curlib)) {
          prfopt(FLMMNUU,riptot,ripctr++);
     }
     if (flo->nlibaxs > 1) {
          prfopt(FLMMNUS,riptot,ripctr++);
     }
     if (haskey(listkey) && !(curlib->flags&FLGDOS)) {
          prfopt(FLMMNUL,riptot,ripctr++);
     }
     prfopt(FLMMNUP,riptot,ripctr++);
     if (isflop(curlib)) {
          prfopt(FLMMNUO,riptot,ripctr++);
     }
     prfmsg(FLMMNUX);
     usrptr->substt=MMENU;
}

VOID
opmenu(VOID)                       /* display operations menu              */
{
     prfmsg(FLOMNU);
     if (curlib->flags&FLGDOS) {
          prfmsg(haskey(flsysop) ? FLOMNUCD : FLOMNUE3);
     }
     else {
          prfmsg(haskey(flsysop) ? FLOMNUC : FLOMNUE2);
     }
}

VOID
promptin(VOID)                     /* display the prompt                   */
{
     INT clingsav;

     setftu();
     if (usrptr->state != flstt) {
          return;
     }
     switch (usrptr->substt) {
     case SELLIB2:
     case SELLIB3:
          prfmsg(SELLIB);
          break;
     case TRANSPRT:
          prfmsg(PROTOS);
          outprf(usrnum);
          setftu();
          pmcare=pmvalu=FTFXMT;
          clingsav=clingo;
          if (isripu()) {
               clingo=0;
          }
          (*hdlpmu)();
          clingo=clingsav;
          setmbk(flmsg);
          prfmsg(usrptr->substt);
          break;
     case APPMENU:
          setmisc(spr("%d",getaufil(0,0)));
          prfmsg(APPMENU);
          setmisc("");
          break;
     case RENNAME:
          setmisc(flo->miscfil);
          prfmsg(RENNAME);
          setmisc("");
          break;
     case DELMENU:
          setmisc(spr("%d",nlibtagd()));
          prfmsg(DELMENU);
          setmisc("");
          break;
     case MOVMENU:
          setmisc(spr("%d",nlibtagd()));
          prfmsg(MOVMENU);
          setmisc("");
          break;
     case UNAPPMNU:
          setmisc(spr("%d",getaufil(0,1)));
          prfmsg(UNAPPMNU);
          setmisc("");
          break;
     case OPMENU:
          if (!(usrptr->flags&INJOIP) || (usrptr->flags&ABOIP)) {
               opmenu();
          }
          prfmsg(OPMENU);
          break;
     case TAGMAN:
          if (ftuptr->numftg > 0) {
               rstrxf();
               taglist();
               break;
          }
          else if (flo->flags&OFTGMAN) {
               usrptr->substt=FILELST0;
               rebuild(2);
               unbreak();
               btuinj(usrnum,CYCLE);
               btutrg(usrnum,255);
               return;
          }
          retmenu(0);
          mainmenu();
          prfmsg(MMENU);
          break;
     case MMENU:
          if (isripu() || !(usrptr->flags&INJOIP) || (usrptr->flags&ABOIP)) {
               mainmenu();
          }
          prfmsg(MMENU);
          break;
     case ENTUADNM:
          switch (flo->retstt) {
          case APPMENU:
               setmisc("approve");
               break;
          case DELMENU:
               setmisc("delete");
               break;
          case -DELMENU:
               setmisc("rename");
               break;
          case MOVMENU:
               setmisc((flo->flags&MOVFLAG) ? "copy" : "move");
               break;
          case UNAPPMNU:
               setmisc("unapprove");
          }
          prfmsg(ENTUADNM);
          setmisc("");
          break;
     case CHUNJ:
          prfmsg(flo->index ? CHUNU : CHUNJ);
          break;
     case CHAINMNU:
          scanlib(0,curlib);
          if (chjoined(curlib,curlib->libname)) {
               curlib->libs--;
          }
          prfmsg(CHAINMNU,curlib->libs);
          break;
     case FILMOVA:
          break;
     case WARNMARK:
          prfmsg((flo->miscflag%2) ? WARNMARK : WARNMARB);
          break;
     case ASKNAME:
          prfmsg(flo->styp == 3 ? ASKNAME : ASKWILD);
          break;
     case VIEWASC:
          switch (candlnow(flo->tags[flo->hold].libname,
                           flo->tags[flo->hold].filname)) {
          case 0:
               prfmsg(VIEWASCN);
               break;
          case 1:
               prfmsg(VIEWASC);
               break;
          default:
               prfmsg(VIEWASCC);
          }
          break;
     case FILELST2:
          usrptr->substt=FILELST1;
          break;
     case FILELST1:
          prfmsg((flo->atend&LSTBACK) ? ENDLISTX : LISTPAUX);
          break;
     case ASKWHLPA:
          if ((usrptr->flags&INJOIP) && isripu()) {
               prfmsg(usrptr->substt);
          }
          prfmsg(ASKWHLP1);
          break;
     case ASKWHLPB:
          if ((usrptr->flags&INJOIP) && isripu()) {
               prfmsg(usrptr->substt);
          }
          prfmsg(ASKWHLP2);
          break;
     case ASKWHLPC:
          if ((usrptr->flags&INJOIP) && isripu()) {
               prfmsg(usrptr->substt);
          }
          prfmsg(ASKWHLP3);
          break;
     case DODESC:
          ulfileq(0);
          prfmsg(DODESC);
          break;
     case LOGOFF2:
          prfmsg(CLRSCN);
          prfmsg(DEFRIPM);
          prfmsg(LOGOFF2);
          break;
     case LOGOFF3:
          prfmsg(CLRSCN);
          prfmsg(DEFRIPM);
          prfmsg(LOGOFF3);
          break;
     case PLSWAIT:
          prfmsg(CLRSCN);
          prfmsg(DEFRIPM);
          prfmsg(PLSWAIT);
          break;
     case ENTDLFIL:
     case BIGCOPY:
     case SELLIB:
     case PREFERS:
     case DELLIBNM:
     case PRESENTR:
     case ENTULFIL:
     case DELFIL:
     case LOGOFF:
     case MANAGMNU:
     case FLSTYPA:
     case FLSLIB:
     case ASKWORD:
     case ASKOFF:
     case ASKTYPA:
     case ASKLIB:
     case FDESCED:
     case MOVPATH:
     case RENCYC:
     case ULMOD:
     case DOSO:
     case CLIBNAM:
     case FLBLIST:
     case OVERW:
     case RENAME:
     case RENAMO:
     case BADNAME:
          prfmsg(usrptr->substt);
     default:
          prf("");
     }
     outprf(usrnum);
     prf("");
}

VOID
retmenu(                           /* return to main/op menu, or exit      */
INT opermenu)
{
     cncall();
     donewrit(-1);
     usrptr->substt=(opermenu ? OPMENU : MMENU);
     ((struct fluson *)ptrblok(flomem,usrnum))->flags&=~INMVCPY;
     condex();
}

VOID
buildview(                         /* build viewscreen                     */
INT item)
{
     movmem(vdaptr,&vdaptr[vdd],vdd);
     stzcpy(flo->key1.filname,flo->tags[item].filname,FLFILENM);
     stzcpy(flo->key1.libname,flo->tags[item].libname,FLNAMESZ);
     setmbk(flmsg);
     prfmsg(CLRSCN);
     outprf(usrnum);
     unbreak();
     bgnfiled(1);
     movmem(&vdaptr[vdd],vdaptr,vdd);
     if (flo->flags&USRANSI) {
          usrptr->substt=ENTRETT;
          prfmsg(candlnow(flo->key1.libname,flo->key1.filname) > DOWNLOD ?
           ENTRETV : ENTRETT);
     }
     if (flo->tdline[item] < 0) {
          prfmsg(ENTRETRU);
     }
}

VOID
retoin(VOID)                       /* passed to return to this module      */
{
     INT tagnum;

     if (usrptr->state == flstt) {
          return;
     }
     prf("");
     outprf(usrnum);
     prf("");
     fluoff(usrnum);
     usrptr->state=flstt;
     if (flo->retstt == ENTRETT
      || flo->retstt == FILELST0
      || flo->retstt == VIEWASC) {
          tagnum=alrtag(flo->tags[flo->hold].libname,
               flo->tags[flo->hold].filname);
          if (tagnum != 0) {
               ftag=tagoff(--tagnum);
               ftag->status=-abs(ftag->status);
               for (tagnum=0 ; tagnum < ftuptr->numftg ; tagnum++) {
                    ftgptr=&ftgusr[tagnum];
                    if (spc == ftag) {
                         untag(tagnum);
                         removetg(tagnum);
                    }
               }
          }
          unbreak();
          if (flo->retstt == VIEWASC) {
               setmbk(flmsg);
               usrptr->substt=VIEWASC;
               switch (candlnow(flo->tags[flo->hold].libname,
                  flo->tags[flo->hold].filname)) {
               case 0:
                    prfmsg(VIEWASCN);
                    break;
               case 1:
                    prfmsg(VIEWASC);
                    break;
               default:
                    prfmsg(VIEWASCC);
               }
               outprf(usrnum);
               prf("");
          }
          else {
               if (flo->retstt == ENTRETT) {
                    setmbk(flmsg);
                    prfmsg(LSTFRAME);
                    if (!isripu()) {
                         prf("\r");
                    }
                    buildview(flo->hold);
               }
               else {
                    prf("\r");
                    usrptr->substt=FILELST0;
                    rebuild(2);
               }
               prf("");
               outprf(usrnum);
               prf("");
               btutrg(usrnum,255);
               usrptr->flags|=NOINJO;
          }
          btuinj(usrnum,CYCLE);
     }
     else {
          usrptr->substt=TAGMAN;
          setmbk(flmsg);
          promptin();
          if (usrptr->substt != MMENU) {
               flo->retstt=TAGMAN;
          }
          prf("");
     }
}

VOID
retoinx(VOID)                      /* passed to return, does less          */
{
     usrptr->state=flstt;
     usrptr->substt=flo->retstt;
     flo->retstt=MMENU;
}

VOID
retoinl(VOID)                      /* passed to return from listing()      */
{
     retoinx();
     setmbk(flmsg);
     prf("");
     prfmsg(usrptr->substt);
     outprf(usrnum);
     prf("");
}

VOID
rstcrd(VOID)                       /* restore from zapcrd                  */
{
     usrptr->crdrat=flo->crdrat;
     usrptr->flags&=~(flo->nozap^NOZAP);
}

VOID
setbusy(VOID)                      /* set user's busy flag                 */
{
     flo->flags|=UNOINJO;
     if (!(flo->flags&USRANSI) || !(usrptr->flags&NOINJO)) {
          flo->flags&=~UNOINJO;
          if (flo->flags&USRANSI) {
               usrptr->flags|=NOINJO;
          }
     }
}

VOID
statstrt(VOID)                     /* begin fsd : line edit                */
{
     setmbk(flmsg);
     fluoff(usrnum);
     switch (usrptr->substt) {
     case LIBEDTN:
          btuoes(usrnum,0);
          if (libedt->lib.libname[0] != '\0') {
               clrprf();
               prfmsg(LIBEDITX,libedt->lib.libname,
                      ((libedt->lib.flags&FLGDOS) ? "(OS-ONLY)" : ""),
                      ncdatel(libedt->lib.day),nctime(libedt->lib.time));
               outprf(usrnum);
          }
          libeditp(LIBEDTN,0);
          fsdscb->flddat[FLDDATE].flags|=FFFAVD;
          fsdscb->flddat[FLDTIME].flags|=FFFAVD;
          fsdscb->flddat[FLDNAME].flags|=FFFAVD;
          fsdscb->flddat[FLDDOSO].flags|=FFFAVD;
          fsdscb->flddat[FLDPATH].flags|=FFFNSP;
          fsdscb->flddat[FLDVIS].flags|=FFFNSP;
          fsdscb->flddat[FLDDLD].flags|=FFFNSP;
          fsdscb->flddat[FLDULD].flags|=FFFNSP;
          fsdscb->flddat[FLDOVW].flags|=FFFNSP;
          fsdscb->flddat[FLDAPU].flags|=FFFNSP;
          fsdscb->flddat[FLDLOP].flags|=FFFNSP;
          if (libedt->lib.flags&FLGDOS) {
               fsdscb->flddat[FLDHID].flags|=FFFAVD;
               fsdscb->flddat[FLDCBD].flags|=FFFAVD;
               fsdscb->flddat[FLDROY].flags|=FFFAVD;
               fsdscb->flddat[FLDOVW].flags|=FFFAVD;
               fsdscb->flddat[FLDAPU].flags|=FFFAVD;
          }
          if (auditall) {
               fsdscb->flddat[FLDAUL].flags|=FFFAVD;
               fsdscb->flddat[FLDADL].flags|=FFFAVD;
          }
          if (freeuls) {
               fsdscb->flddat[FLDFUL].flags|=FFFAVD;
          }
          fsdego(libeditv,libeditd);
          outprf(usrnum);
          break;
     case FILEDTN:
          btuoes(usrnum,0);
          fileditp(FILEDTN,0,0);
          fsdscb->flddat[FFDNAME].flags|=FFFAVD;
          fsdscb->flddat[FFDLIB].flags|=FFFAVD;
          fsdscb->flddat[FFDDATE].flags|=FFFAVD;
          fsdscb->flddat[FFDTIME].flags|=FFFAVD;
          fsdscb->flddat[FFDSIZE].flags|=FFFAVD;
          fsdscb->flddat[FFDDLT].flags|=FFFAVD;
          fsdscb->flddat[FFDCHG].flags|=FFFAVD;
          if (notapped(flo->udate)) {
               fsdscb->flddat[FFDULD].flags|=FFFAVD;
               fsdscb->flddat[FFDULT].flags|=FFFAVD;
          }
          if (!isflop(curlib)) {
               fsdscb->flddat[FFDUSER].flags|=FFFAVD;
               fsdscb->flddat[FFDDL].flags|=FFFAVD;
               fsdscb->flddat[FFDULD].flags|=FFFAVD;
               fsdscb->flddat[FFDULT].flags|=FFFAVD;
          }
          fsdego(fileditv,fileditd);
          outprf(usrnum);
     }
}

INT
getaufil(                          /* check tagspc is ok to approve/unapp  */
INT wipe,
INT unapp)
{
     struct taglib *tag;
     struct fllib *savclb;
     INT loop,retval=0;

     savclb=curlib;
     for (loop=0 ; loop < systags ; loop++) {
          tag=tagoff(loop);
          if (tag->status > TGEMPTY
           && ((!notapped(tag->udate) && unapp) || (notapped(tag->udate) && !unapp))
           && usrnum == tag->usrnum) {
               curlib=libfind(tag->libname);
               if (curlib != NULL && isflop(curlib)) {
                    if (retval == 0) {
                         stzcpy(flo->key1.filname,tag->filname,FLFILENM);
                         stzcpy(flo->key1.libname,tag->libname,FLNAMESZ);
                         if (wipe) {
                              stzcpy(tag->udate,unapp ? NOTAPPED
                                                    : ddat2srt(today()),DATESZ);
                         }
                    }
                    retval++;
               }
          }
     }
     curlib=savclb;
     return(retval);
}

INT
candlnow(                          /* can user d/l or view now?            */
CHAR *libname,
CHAR *filname)
{
     struct fllib *libptr;
     CHAR *ext;

     setftu();
     if ((libptr=libfind(libname)) != NULL) {
          if (!(libptr->flags&FLGCBD)
           && (maxtags-ftuptr->numftg) > 0) {
               if ((ext=strchr(filname,'.')) == NULL) {
                    ext="";
               }
               else {
                    ext++;
               }
               return(viewmode(ext));
          }
     }
     return(0);
}

INT
chjoined(                          /* see if check is joined to Library    */
struct fllib *libptr,
CHAR *check)
{
     INT loop;

     if (libptr != NULL) {
          for (loop=0 ; loop < FLNMCATS ; loop++) {
               if (sameas(check,libptr->cat[loop])) {
                    return(1);
               }
          }
     }
     return(0);
}

INT
chjoin(                            /* join/unjoin new to l                 */
struct fllib *libptr,
struct fllib *newlib,
INT unjoin)
{
     INT loop;
     CHAR *catptr;

     if (libptr != NULL && newlib != NULL) {
          for (loop=0 ; loop < FLNMCATS ; loop++) {
               catptr=newlib->cat[loop];
               if (!unjoin) {
                    if (sameas(catptr,libptr->libname)) {
                         prfmsg(LIBALRJN,newlib->libname);
                         break;
                    }
                    else if (*catptr == '\0') {
                         newlib->flags|=LIBCHN;
                         stzcpy(catptr,libptr->libname,FLNAMESZ);
                         newjoins=TRUE;
                         return(1);
                    }
               }
               else if (sameas(libptr->libname,catptr)) {
                    catptr[0]='\0';
                    movmem(newlib->cat[loop+1],catptr,
                       (FLNMCATS-loop-1)*FLNAMESZ);
                    newlib->cat[FLNMCATS-1][0]='\0';
                    newlib->flags|=LIBCHN;
                    newjoins=TRUE;
                    return(1);
               }
          }
     }
     return(0);
}

VOID
listjoin(VOID)                     /* list Libraries joined to curlib      */
{
     INT loop,loop2,num=0;
     struct fllib *libptr;

     for (loop=0 ; loop < numoflib ; loop++) {
          libptr=liboff(loop);
          if (libptr->cat[0][0] != '\0' && curlib != libptr) {
               for (loop2=0 ; loop2 < FLNMCATS ; loop2++) {
                    if (sameas(libptr->cat[loop2],curlib->libname)) {
                         prf("%-8s ",libptr->libname);
                         if ((++num%8) == 0) {
                              prf("\r");
                         }
                         outprf(usrnum);
                         prf("");
                    }
               }
          }
     }
     if (num == 0) {
          prfmsg(CHAINO);
     }
}

INT
profane(                           /* return true if stg is profane        */
const CHAR *stg)
{
     INT pfnlvl;

     if ((pfnlvl=profan((CHAR *)stg)) != 0) {
          if (isflop(curlib)) {
               pfnlvl=0;
          }
          else if (pfnlvl > pfnceil) {
               pfnlvl=pfnceil;
          }
     }
     return(pfnlvl);
}

INT
wldmatch(                          /* match wild word to ordinary word     */
CHAR *wild,                        /* ... word including * or ?s           */
CHAR *sfnm)                        /* ... word to match against            */
{
     CHAR *sptr,chr,*cptr,cmp;

     for (sptr=wild,cptr=sfnm ; (chr=toupper(*sptr)) != '\0' ; sptr++,cptr++) {
          cmp=toupper(*cptr);
          if (chr == '*') {
               return(1);
          }
          if ((chr != '?' && chr != cmp) || cmp == '\0') {
               return(0);
          }
     }
     return(*cptr == '\0');
}

INT
compwild(                          /* does filename qualify as wildfile?   */
CHAR *wildfile,
CHAR *filename)
{
     CHAR *stg;
     CHAR wtot[13],wname[9],wext[4];
     CHAR ftot[13],fname[9],fext[4];

     stzcpy(wtot,wildfile,13);
     stg=strchr(wtot,'.');
     if (stg == NULL) {
          stg="*";
     }
     else {
          *stg++='\0';
     }
     stzcpy(wname,wtot,9);
     stzcpy(wext,stg,4);
     stzcpy(ftot,filename,13);
     stg=strchr(ftot,'.');
     if (stg == NULL) {
          fext[0]='\0';
     }
     else {
          *stg++='\0';
          stzcpy(fext,stg,4);
     }
     stzcpy(fname,ftot,9);
     return(wldmatch(wname,fname) && wldmatch(wext,fext));
}

INT
space(VOID)                        /* check space for copying a file       */
{
     return(dskfre(copydir)-(thresh/1024L) > 0L);
}

VOID
dncfin(                            /* finalize d/l charges                 */
INT endok,                         /* 0=aborted 1=ended ok                 */
LONG bytxfer,                      /* # of bytes actually sent             */
struct fllib *libptr)              /* Library file was in                  */
{
     if (endok || chgabt) {
          dlcharge(dnlprc(bytxfer,libptr),libptr);
     }
}

INT
weirddir(                          /* see if dir is suspicious             */
CHAR *dirpath)
{
     INT retval=0;

     if (isfile(spr("%s"SLS"*.exe",dirpath))) {
          retval=1;
     }
     else if (isfile(spr("%s"SLS"*.com",dirpath))) {
          retval=1;
     }
     else if (isfile(spr("%s"SLS"*.bat",dirpath))) {
          retval=1;
     }
     if (retval) {
          shocst("GALFIL: WARNING - COPYDIR DIRECTORY",
                 "Directory not erased, it has .COM, .EXE, or .BAT files");
     }
     return(retval);
}

INT
isansiu(VOID)                      /* is an ansi user w/ screen settings?  */
{
     return (isripu()
          || ((usaptr->ansifl&ANSON)
            && usaptr->scnfse >= 23
            && usaptr->scnwid >= 80));
}

VOID
touch(                             /* get date from src and give to dest   */
CHAR *src,
CHAR *dest)
{
     FILE *fp;

     if ((fp=fopen(src,FOPRB)) != NULL) {
          setFileGMT(dest,getFileGMT(src));
          fclose(fp);
     }
}

VOID
untagall(                          /* untag all files                      */
CHAR *libname,
CHAR *filname)
{
     struct taglib *tag;
     INT loop;

     for (loop=0 ; loop < systags ; loop++) {
          if (sameas((tag=tagoff(loop))->libname,libname)) {
               if (filname[0] == '\0' || sameas(filname,tag->filname)) {
                    tag->status=-abs(tag->status);
               }
          }
     }
}

INT
exfile(                            /* examine file closely                 */
struct fllib *libptr,
struct key0 *key)
{
     struct ffblk fb;
     INT del=0,upd=0;

     if (fndfile(&fb,spr("%s"SLS"%s",libpath(libptr),flf->filname),0)) {
          if (fb.ff_fsize != flf->siz || fb.ff_ftime != flf->tim
           || !sameas(ncdatel(fb.ff_fdate),srt2datl(flf->fdate))) {
               upd=1;
          }
          libptr->totbytes+=flclfit(fb.ff_fsize,libptr->cluster);
     }
     else {
          del=1;
     }
     if ((del || upd) && dfaAcqEQ(NULL,key,COMPLUF)) {
          if (del) {
               stzcpy(flf->udate,NOTAPPED,DATESZ);
          }
          if (upd) {
               stzcpy(flf->fdate,ddat2srt(fb.ff_fdate),DATESZ);
               flf->siz=fb.ff_fsize;
               flf->tim=fb.ff_ftime;
          }
          dfaUpdateV(NULL,FLFILREC+strlen(flf->desc)+1);
     }
     return(1);
}

VOID
cleanit(                           /* cleanup routine                      */
INT total)
{
     INT loop,appwait,numfiles,countit;
     LONG totbytes;
     UINT clustsiz;
     struct fllib *libptr;
     struct key0 key;

     dfaSetBlk(flfdat);
     for (loop=0 ; loop < numoflib ; loop++) {
          libptr=liboff(loop);
          if (libptr->libname[0] != '\0') {
               appwait=numfiles=0;
               setmem(&key,sizeof(struct key0),0);
               stzcpy(key.libname,libptr->libname,FLNAMESZ);
               totbytes=libptr->totbytes;
               libptr->totbytes=0L;
               clustsiz=clsize(libpath(libptr));
               if (libptr->cluster != clustsiz) {
                    libptr->cluster=clustsiz;
                    libptr->flags|=LIBCHN;
               }
               while (dfaAcqGT(NULL,&key,COMPLUF)
                && sameas(flf->libname,key.libname)) {
                    stzcpy(key.filname,flf->filname,FLFILENM);
                    stzcpy(key.udate,flf->udate,DATESZ);
                    countit=1;
                    if (total && !(libptr->flags&FLGRDO)
               && (!(libptr->flags&FLGCBD)
                   || libptr->path[0] != '\0')) {
                         countit=exfile(libptr,&key);
                    }
                    if (!total) {
                         libptr->totbytes=totbytes;
                    }
                    if (countit) {
                         numfiles++;
                         if (notapped(flf->udate)) {
                              appwait++;
                         }
                    }
               }
               if (appwait != libptr->appwait
             || numfiles != libptr->numfiles
             || totbytes != libptr->totbytes) {
                    libptr->appwait=appwait;
                    libptr->numfiles=numfiles;
                    libptr->flags|=LIBCHN;
               }
          }
     }
     dfaRstBlk();
}

CHAR *
manytims(                          /* return "> 99K" or the number         */
LONG howmany)
{
     static CHAR retval[6];

     if (howmany <= 0L) {
          return("0");
     }
     if (howmany > 99000L) {
          return("> 99K");
     }
     sprintf(retval,"%ld",howmany);
     return(retval);
}

struct taglib *
tagoff(                            /* return pointer to tagged file spec   */
INT index)
{
     return((struct taglib *)ptrblok(ftagmem,index));
}

CHAR *
isedtlib(VOID)                     /* userid currently editor of a Library */
{
     for (othusn=0 ; othusn < nterms ; othusn++) {
          if (othusn != usrnum) {
               othusp=usroff(othusn);
               if (othusp->usrcls == ACTUSR) {
                    if (othusp->state == flstt) {
                         switch (othusp->substt) {
                         case DOSO:
                         case CLIBNAM:
                              return(uacoff(othusn)->userid);
                         }
                    }
                    else {
                         if (((struct fluson *)ptrblok(flomem,
                            othusn))->flags&ISEDLIB) {
                              return(uacoff(othusn)->userid);
                         }
                    }
               }
          }
     }
     return(NULL);
}

VOID
countupl(VOID)                     /* count uploads for all Libraries      */
{
     struct fllib *libptr;
     INT loop;

     for (loop=0 ; loop < numoflib ; loop++) {
          libptr=liboff(loop);
          if (libptr->libname[0] != '\0' && !(libptr->flags&FLGRDO)
           && (!(libptr->flags&FLGCBD) || libptr->path[0] != '\0')) {
               inicount(libptr->libname);
               do {
                    ulcount();
               } while (countlib[0] != '\0');
          }
     }
}

VOID
chuldate(                          /* add/subtract new upload today        */
struct fllib *libptr,
const CHAR *date,
INT add)
{
     SHORT ago,*numuls;

     if (!sameas(date,NOTAPPED) && libptr != NULL) {
          ago=cofdat(today())-cofdat(dcdate(srt2datl(date)));
          if (ago >= 0 && ago < ULDAYS) {
               numuls=&libptr->newfiles[ago];
               *numuls+=(add ? 1 : -1);
               if (*numuls < 0) {
                    *numuls=0;
               }
               libptr->flags|=LIBCHN;
          }
     }
}

INT
dlfrom(                            /* can current user d/l from a Library? */
CHAR *libname)                     /* ... Library name                     */
{
     return(libname[0] != '\0' && dlfroml(libfind(libname)));
}

INT
dlfroml(                           /* can current user d/l from a Library? */
struct fllib *libptr)              /* ... Library pointer                  */
{
     return(libptr != NULL && haslibkey(libptr,libptr->dlkey));
}

VOID
dlcant(VOID)                       /* error - cannot download that file    */
{
     prfmsg(BEEP);
     if (!(flo->flags&XDLBEEP) && (flo->flags&STOPLST)) {
          prfmsg(usrptr->substt=POPWIN5);
          flo->flags|=XDLBEEP;
     }
}

VOID
setmisc(                           /* set the flmisc text variable         */
CHAR *stg)
{
     stzcpy(flmisc,stg,MISCSIZE);
}

INT
viewmode(                          /* given extension, is there a view mode*/
CHAR *ext)
{
     INT loop,retval=NOTVIEW;

     for (loop=0 ; loop < NVIEWS && retval == NOTVIEW; loop++) {
          if (sameas(ext,mvarr[loop].ext)) {
               retval=mvarr[loop].mode;
               if (retval == CSTVIEW) {
                    flo->rouptr=mvarr[loop].rouptr;
               }
          }
     }
     return(retval == NOTVIEW ? DOWNLOD : retval);
}

INT
register_modeview(                 /* register a CTRL-V viewing mode       */
CHAR *ext,                         /* ...extension to treat                */
INT mode,                          /* ...mode to use                       */
VOID (*rouptr)())                  /* ...if mode CSTVIEW, custom view      */
{
     INT loop;

     for (loop=0 ; loop < NVIEWS ; loop++) {
          if (mvarr[loop].ext[0] == '\0') {
               stzcpy(mvarr[loop].ext,ext,4);
               mvarr[loop].mode=mode;
               if (mode == 5) {
                    mvarr[loop].rouptr=rouptr;
               }
               return(loop);
          }
     }
     return(-1);
}

VOID
iappmenu(                          /* approval of files menu               */
CHAR chr)
{
     switch (chr) {
     case 'T':
          if (getaufil(0,0)) {
               flo->autol=0;
               prfmsg(usrptr->substt=APPING);
               btuinj(usrnum,CYCLE);
          }
          else {
               prfmsg(NONAPP);
          }
          break;
     case 'A':
          stzcpy(flo->u.key0.libname,curlib->libname,FLNAMESZ);
          setmem(flo->u.key0.udate,DATESZ,0);
          setmem(flo->u.key0.filname,FLFILENM,0);
          flo->autol=1;
          prfmsg(usrptr->substt=APPING);
          btuinj(usrnum,CYCLE);
          break;
     case '\0':
     case 'X':
          retmenu(1);
          break;
     case 'N':
          flo->retstt=usrptr->substt;
          usrptr->substt=ENTUADNM;
     }
}

VOID
iunapp(                          /* unapproval of files menu               */
CHAR chr)
{
     switch (chr) {
     case 'T':
          if (getaufil(0,1)) {
               prfmsg(usrptr->substt=UNAPPING);
               btuinj(usrnum,CYCLE);
          }
          else {
               prfmsg(NONUAPP);
          }
          break;
     case '\0':
     case 'X':
          retmenu(1);
          break;
     case 'N':
          flo->retstt=usrptr->substt;
          usrptr->substt=ENTUADNM;
     }
}

VOID
idelmenu(                          /* deletion of files menu               */
CHAR chr)
{
     switch (chr) {
     case 'T':
          if (nlibtagd()) {
               setmbk(flmsg);
               usrptr->substt=DELFIL;
          }
          else {
               prfmsg(CANTNUKE);
          }
          break;
     case '\0':
     case 'X':
          retmenu(1);
          break;
     case 'N':
          flo->retstt=usrptr->substt;
          usrptr->substt=ENTUADNM;
          break;
     case 'R':
          if (!writable(curlib)) {
               prfmsg(CANTRNML);
          }
          else {
               flo->retstt=-usrptr->substt;
               usrptr->substt=ENTUADNM;
          }
          break;
     case 'A':
          if (!(curlib->flags&FLGDOS)) {
               stzcpy(flo->u.key0.libname,curlib->libname,FLNAMESZ);
               setmem(flo->u.key0.udate,DATESZ,0);
               setmem(flo->u.key0.filname,FLFILENM,0);
               flo->autol=2;
               usrptr->substt=APPING;
               prfmsg(DELING);
               btuinj(usrnum,CYCLE);
          }
     }
}

VOID
imovmenu(                          /* move files menu                      */
CHAR chr)
{
     switch (chr) {
     case 'T':
          if (nlibtagd()) {
               setmbk(flmsg);
               usrptr->substt=MOVPATH;
               setmem(flo->miscfil,FLFILENM,0);
          }
          else {
               prfmsg(CANTNUKE);
          }
          flo->flags&=~MOVFLAG;
          break;
     case '\0':
     case 'X':
          retmenu(1);
          break;
     case 'N':
          flo->flags&=~MOVFLAG;
          flo->retstt=usrptr->substt;
          usrptr->substt=ENTUADNM;
          break;
     case 'C':
          flo->flags|=MOVFLAG;
          flo->retstt=usrptr->substt;
          usrptr->substt=ENTUADNM;
          break;
     case 'A':
          if (nlibtagd()) {
               setmbk(flmsg);
               usrptr->substt=MOVPATH;
               setmem(flo->miscfil,FLFILENM,0);
          }
          else {
               prfmsg(CANTNUKE);
          }
          flo->flags|=MOVFLAG;
     }
}

VOID
imovpath(                          /* move files to what Library           */
CHAR *stg)
{
     struct fllib *libptr;

     if (stg[0] == '\0' || sameas(stg,"x")
      || (nlibtagd() == 0 && flo->miscfil[0] == '\0')) {
          setmbk(flmsg);
          retmenu(1);
          return;
     }
     if ((libptr=libfind(stg)) == NULL) {
          prfmsg(CHNOS);
          return;
     }
     if (libptr->flags&FLGDOS) {
          prfmsg(NOTODOS);
          return;
     }
     if (!isflop(libptr)) {
          prfmsg(MOVAXS);
          return;
     }
     if (libptr == curlib) {
          prfmsg(NOCANMOV);
          return;
     }
     if (!writable(libptr)) {
          prfmsg(MOVRDO);
          return;
     }
     stzcpy(flo->misclib,libptr->libname,FLNAMESZ);
     if ((strchr(flo->miscfil,'*') != NULL)
      || (strchr(flo->miscfil,'?') != NULL)) {
          flo->fsrc=fopen(spr("%s"SLS"temptags.%d",copydir,usrnum),
                 FOPWB);
          if (flo->fsrc != NULL) {
               setmem(&flo->u,sizeof(union combo),0);
               stzcpy(flo->u.key4.libname,curlib->libname,FLNAMESZ);
               flo->keymeth=7;
               flo->flags&=~REVSRCH;
               flo->wtnum=0;
               wldstuff(flo->u.key4.filname);
               if (initsrc()) {
                    flo->retstt=WLDSYS;
                    prfmsg(usrptr->substt=CYCIDX);
                    btuinj(usrnum,CYCLE);
                    return;
               }
               else {
                    setmisc(flo->miscfil);
                    prfmsg(usrptr->substt=WLDSYS);
                    setmisc("");
               }
          }
          else {
               usrptr->substt=ENTUADNM;
               return;
          }
     }
     else {
          flo->retstt=usrptr->substt;
          usrptr->substt=FILMOVA;
     }
     unbreak();
     btuinj(usrnum,CYCLE);
}

VOID
ienuadnm(                          /* enter name of file for operations    */
CHAR *stg)
{
     struct fllib *libptr;
     INT update=0;
     INT who;

     if (stg[0] == '\0' || sameas(stg,"x")) {
          usrptr->substt=abs(flo->retstt);
          return;
     }
     if ((strchr(stg,'*') != NULL) || (strchr(stg,'?') != NULL)) {
          if (flo->retstt == -DELMENU) {
               prfmsg(CANTWLDS);
               return;
          }
          stzcpy(flo->miscfil,strupr(stg),FLFILENM);
          if (flo->retstt == MOVMENU) {
               usrptr->substt=MOVPATH;
               return;
          }
          flo->fsrc=fopen(spr("%s"SLS"temptags.%d",copydir,usrnum),FOPWB);
          if (flo->fsrc != NULL) {
               setmem(&flo->u,sizeof(union combo),0);
               stzcpy(flo->u.key4.libname,curlib->libname,FLNAMESZ);
               flo->keymeth=7;
               flo->flags&=~REVSRCH;
               flo->wtnum=0;
               if (initsrc()) {
                    flo->retstt=WLDSYS;
                    prfmsg(usrptr->substt=CYCIDX);
                    btuinj(usrnum,CYCLE);
               }
               else {
                    setmisc(flo->miscfil);
                    prfmsg(usrptr->substt=WLDSYS);
                    setmisc("");
                    unbreak();
                    btuinj(usrnum,CYCLE);
               }
               wldstuff(flo->u.key4.filname);
               return;
          }
     }
     dfaSetBlk(flfdat);
     if (!dfaAcqEQ(NULL,compkey(curlib->libname,stg),COMPLF)) {
          locsysfl(stg);
          return;
     }
     switch (flo->retstt) {
          case APPMENU:
               if (!notapped(flf->udate)) {
                    prfmsg(NOTNEED,"");
               }
               else {
                    stzcpy(flf->udate,ddat2srt(today()),DATESZ);
                    flf->utime=now();
                    update=1;
                    curlib->appwait--;
                    curlib->flags|=LIBCHN;
                    chuldate(curlib,flf->udate,1);
               }
               break;
          case UNAPPMNU:
               if (notapped(flf->udate)) {
                    prfmsg(NOTNEED,"un");
               }
               else {
                    chuldate(curlib,flf->udate,0);
                    stzcpy(flf->udate,NOTAPPED,DATESZ);
                    flf->utime=now();
                    update=2;
                    curlib->appwait++;
                    curlib->flags|=LIBCHN;
               }
               break;
          case -DELMENU: /* renaming file    */
               stzcpy(flo->miscfil,flf->filname,FLFILENM);
               usrptr->substt=RENNAME;
               break;
          case DELMENU:
               if ((who=w2writ(flf->libname,flf->filname,0)) != NOCONFLICT) {
                    prfmsg(DELCFL,uacoff(who)->userid);
                    break;
               }
               stzcpy(flo->miscfil,flf->filname,FLFILENM);
               libptr=curlib;
               if (notapped(flf->udate) && (libptr->appwait > 0)) {
                    libptr->appwait--;
               }
               chuldate(libptr,flf->udate,0);
               libptr->totbytes-=flclfit(flf->siz,libptr->cluster);
               libptr->numfiles--;
               libptr->flags|=LIBCHN;
               dfaDelete();
               untagall(flf->libname,flf->filname);
               prfmsg(DELED);
               donewrit(0);
               if (!longsrch) {
                    prfmsg(usrptr->substt=INDDELK);
                    flo->flags&=~WLDRSLV;
                    btuinj(usrnum,CYCLE);
               }
               else {
                    usrptr->substt=flo->retstt;
               }
               break;
          case MOVMENU:
               stzcpy(flo->miscfil,flf->filname,FLFILENM);
               usrptr->substt=MOVPATH;
               break;
          default:
               usrptr->substt=flo->retstt;
               return;
     }
     if (update) {
          dfaUpdateV(NULL,FLFILREC+strlen(flf->desc)+1);
          prfmsg((update == 2) ? UNAPPED : APPED);
          if (status != CYCLE) {
               prf("\r");
          }
          usrptr->substt=flo->retstt;
     }
}

VOID
idoso(                             /* want this to be an OS-only Library?  */
CHAR chr)
{
     cncall();
     curlib=&libedt->lib;
     if (lingyn(chr) == 'X') {
          setmem(curlib->libname,FLNAMESZ,0);
          retmenu(1);
          return;
     }
     if (lingyn(chr) == 'Y') {
          curlib->flags|=FLGDOS;
     }
     setmem(curlib->libdesc,FLDESCSZ,0);
     curlib->day=today();
     curlib->time=now();
     stzcpy(curlib->libop,getmsg(DEFLOP),KEYSIZ);
     stzcpy(curlib->autoap,getmsg(DEFAPP),KEYSIZ);
     stzcpy(curlib->keyreq,getmsg(FLVKEY),KEYSIZ);
     stzcpy(curlib->overw,getmsg(DEFOVR),KEYSIZ);
     stzcpy(curlib->dlkey,getmsg(FLDKEY),KEYSIZ);
     stzcpy(curlib->ulkey,getmsg(DEFUL),KEYSIZ);
     stzcpy(curlib->primary,defplop,UIDSIZ);
     curlib->maxfil=10000L;
     curlib->maxbyt=10000000L;
     curlib->maxbup=200000L;
     cncall();
     bgnlibed();
}

VOID
iclibnam(                          /* enter Library name to create         */
CHAR *stg)
{
     if (sameas(stg,"X")) {
          retmenu(1);
          return;
     }
     if (valname(stg)) {
          if (libfind(stg) == NULL) {
               curlib=&libedt->lib;
               stzcpy(curlib->libname,fnmcse(stg),FLNAMESZ);
               usrptr->substt=DOSO;
          }
          else {
               prfmsg(LIBEXT);
          }
     }
     else {
          prfmsg(NAMEOLIB);
     }
}

INT
oprmenu(VOID)                     /* operator menu choice handler         */
{
     CHAR chr,*uid;

     if (!isflop(curlib)) {
          return(0);
     }
     switch (chr=cncchr()) {
     case 'X':
          return(0);
     case '\0':
     case '?':
          cncall();
          prfmsg(OPMHLP);
          return(1);
     case 'I':
          if (!notify(0)) {
               prfmsg(NONEAPP);
          }
          flo->retstt=OPMENU;
          usrptr->substt=PRESENTR;
          return(1);
     case 'S':
          usrptr->substt=SELLIB2;
          return(1);
     case 'C':
          if (haskey(flsysop)) {
               if (numoflib == numlib+numladd) {
                    prfmsg(NOMEMLIB);
               }
               else {
                    uid=isedtlib();
                    if (uid == NULL) {
                         usrptr->substt=CLIBNAM;
                    }
                    else {
                         prfmsg(LIBNOEDT,uid);
                    }
               }
               return(1);
          }
          break;
     case 'U':
     case 'A':
          if (!(curlib->flags&FLGDOS)) {
               deresume();
               usrptr->substt=(chr == 'U' ? UNAPPMNU : APPMENU);
               return(1);
          }
          break;
     case 'R':
          if (!(curlib->flags&FLGDOS)) {
               deresume();
               usrptr->substt=DELMENU;
               return(1);
          }
          break;
     case 'V':
          if (!(curlib->flags&FLGDOS)) {
               if ((uid=inmvcpy()) == NULL) {
                    usrptr->substt=MOVMENU;
                    flo->flags|=INMVCPY;
               }
               else {
                    prfmsg(SYSMVCPY,uid);
               }
               return(1);
          }
          break;
     case 'F':
          if (!(curlib->flags&FLGDOS)) {
               usrptr->substt=FDESCED;
               return(1);
          }
          break;
     case 'T':
          if (haskey(flsysop)) {
               usrptr->substt=TAGSTAT;
               flo->index=0;
               flo->flags&=~TLSTDSP;
               btuinj(usrnum,CYCLE);
               return(1);
          }
          break;
     case 'D':
          if (haskey(flsysop)) {
               usrptr->substt=DELLIBNM;
               return(1);
          }
          break;
     case 'L':
          if (haskey(flsysop) && !(curlib->flags&FLGDOS)) {
               if (writable(curlib)) {
                    flo->miscflag=1;
                    usrptr->substt=BIGCOPY;
               }
               else {
                    prfmsg(CANTULR);
               }
               return(1);
          }
          break;
     case 'M':
          if (haskey(flsysop) && !(curlib->flags&FLGDOS)) {
               usrptr->substt=MANAGMNU;
               flo->flags&=~APPTHEM;
               return(1);
          }
          break;
     case 'E':
          cncall();
          if (haskey(flsysop)) {
               uid=isedtlib();
               if (uid == NULL) {
                    bgnlibed();
                    return(2);
               }
               else {
                    prfmsg(LIBNOEDT,uid);
                    return(1);
               }
          }
          break;
     case 'J':
          if (!(curlib->flags&FLGDOS)) {
               usrptr->substt=CHAINMNU;
               return(1);
          }
          break;
     }
     prfmsg(NOTCMD);
     retmenu(1);
     return(1);
}

CHAR *
inmvcpy(VOID)                      /* is a sysop moving/copying files      */
{
     for (othusn=0 ; othusn < nterms ; othusn++) {
          if (othusn != usrnum) {
               othusp=usroff(othusn);
               if (othusp->usrcls == ACTUSR) {
                    if (othusp->state == flstt) {
                        if (((struct fluson *)
                              ptrblok(flomem,othusn))->flags&INMVCPY) {
                              return(uacoff(othusn)->userid);
                         }
                    }
               }
          }
     }
     return(NULL);
}

VOID
loadldsc(                          /* load description up for lib          */
struct libdisk *libdptr)           /* null = use curlib and libupd         */
{
     struct fllib *lib;
     struct libdisk *libact;
     INT loop;

     if (libdptr == NULL) {
          if (curlib == NULL) {
               setmem(libupd,sizeof(struct libdisk),0);
               return;
          }
     }
     dfaSetBlk(flldat);
     lib=(libdptr != NULL ? &libdptr->lib : curlib);
     libact=(libdptr != NULL ? libdptr : libupd);
     if (dfaAcqEQ(libupd,lib->libname,0)) {
          if (libdptr != NULL) {
               for (loop=0 ; loop < NLDLIN ; loop++) {
                    stzcpy(libact->ldesc[loop],libupd->ldesc[loop],FLLDESCS);
               }
          }
     }
     else {
          for (loop=0 ; loop < NLDLIN ; loop++) {
               libact->ldesc[loop][0]='\0';
          }
     }
     dfaRstBlk();
}

VOID
bgnlibed(VOID)                     /* begin edit or creation of Library    */
{
     CHAR *stg;

     if (curlib != &libedt->lib) {
          movmem(curlib,&libedt->lib,sizeof(struct fllib));
          curlib=&libedt->lib;
     }
     loadldsc(libedt);
     if (isansiu()) {
          fsdrhd(spr("%s",getmsg(EDITLIBO)));
          outprf(usrnum);
          libeditp(usrptr->substt=LIBEDTA2,1);
          stg=getasc(fsdusr->tmpmsg);
          if (curlib->flags&FLGDOS) {
               fsdscb->flddat[FLDHID].flags|=FFFAVD;
               tpwipe(stg,FLDHID,3,3);
               fsdscb->flddat[FLDCBD].flags|=FFFAVD;
               tpwipe(stg,FLDCBD,3,3);
               fsdscb->flddat[FLDROY].flags|=FFFAVD;
               tpwipe(stg,FLDROY,3,1);
               fsdscb->flddat[FLDOVW].flags|=FFFAVD;
               tpwipe(stg,FLDOVW,4,1);
               fsdscb->flddat[FLDAPU].flags|=FFFAVD;
               tpwipe(stg,FLDAPU,4,1);
          }
          fsdbkg(stg);
          fsdscb->flddat[FLDNAME].flags|=FFFAVD;
          fsdscb->flddat[FLDDATE].flags|=FFFAVD;
          fsdscb->flddat[FLDTIME].flags|=FFFAVD;
          fsdscb->flddat[FLDPATH].flags|=FFFNSP;
          fsdscb->flddat[FLDVIS].flags|=FFFNSP;
          fsdscb->flddat[FLDDLD].flags|=FFFNSP;
          fsdscb->flddat[FLDULD].flags|=FFFNSP;
          fsdscb->flddat[FLDOVW].flags|=FFFNSP;
          fsdscb->flddat[FLDAPU].flags|=FFFNSP;
          fsdscb->flddat[FLDLOP].flags|=FFFNSP;
          if (auditall) {
               fsdscb->flddat[FLDAUL].flags|=FFFAVD;
               fsdscb->flddat[FLDADL].flags|=FFFAVD;
          }
          if (freeuls) {
               fsdscb->flddat[FLDFUL].flags|=FFFAVD;
          }
          fsdscb->flddat[FLDDOSO].flags|=FFFAVD;
          fsdego(libeditv,libeditd);
     }
     else {
          libeditp(LIBEDTN,-1);
          btuoes(usrnum,1);
          usrptr->substt=LIBEDTN;
     }
     outprf(usrnum);
     flo->flags|=ISEDLIB;
}

VOID
cdsptags(VOID)                     /* display files a user has tagged      */
{
     while (btuoba(usrnum) > (outbsz-1024)) {
          if (flo->index == 0) {
               prfmsg(TAGSTAT);
          }
          ftag=tagoff(flo->index);
          if (ftag != NULL && ftag->status != TGEMPTY
           && ftag->usrnum >= 0 && ftag->usrnum < nterms) {
               prf(" %-8.8s %-12.12s %-29.29s [%d] ",ftag->libname,
             (sameas("*",ftag->filname) ? ftag->wldspc : ftag->filname),
             uacoff(ftag->usrnum)->userid,ftag->status);
               if (sameas("*",ftag->filname)) {
                    prf("files: %d, bytes: %s",ftag->nwld,l2as(ftag->size));
               }
               else {
                    switch (ftag->status) {
                    case TGLOCAL:
                         prf("DL ready, local drive");
                         break;
                    case TGINWAIT:
                         prf("Wait for local copy");
                         break;
                    case TGCOPY:
                         prf("Being copied locally");
                         break;
                    case TGOTHER:
                         prf("Waiting for copy");
                         break;
                    case TGSERVER:
                         prf("Being copied");
                         break;
                    case TGDLTMP:
                         prf("DL ready, temp area");
                         break;
                    default:
                         if (ftag->status < 0) {
                              prf("D/L over, clean up");
                         }
                         else {
                              prf("???");
                         }
                    }
               }
               prf("\r");
               flo->flags|=TLSTDSP;
               outprf(usrnum);
          }
          if (++flo->index >= systags) {
               if (!(flo->flags&TLSTDSP)) {
                    clrprf();
                    prfmsg(NONETAGD);
               }
               else {
                    prfmsg(TAGSTATF);
               }
               retmenu(1);
               opmenu();
               prfmsg(OPMENU);
               outprf(usrnum);
               prf("");
               return;
          }
     }
     btuinj(usrnum,CYCLE);
     prf("");
     outprf(usrnum);
     prf("");
}

VOID
wipetag(VOID)                      /* clear tag flags                      */
{
     INT loop=0;

     while (loop < NLISTER) {
          flo->tdline[loop++]=0;
     }
     flo->atend=LSTFILS;
}

INT
libchg(VOID)                       /* update changed LIBs                  */
{
     struct fllib *libptr;
     INT loop,mark=-1,retval=0;

     for (loop=0 ; loop < numoflib ; loop++) {
          libptr=liboff(loop);
          if (libptr->flags&LIBONG) {
               libptr->flags|=LIBCHN;
               libptr->flags&=~LIBONG;
          }
          else if (libptr->flags&LIBCHN) {
               mark=loop;
               break;
          }
     }
     if (mark >= 0) {
          libptr=liboff(mark);
          libptr->flags&=~LIBCHN;
          dfaSetBlk(flldat);
          if (dfaAcqEQ(libupd,libptr->libname,0)) {
               movmem(libptr,&libupd->lib,sizeof(struct fllib));
               dfaUpdate(libupd);
          }
          setmem(libupd,sizeof(struct libdisk),0);
          dfaRstBlk();
          retval=1;
     }
     return(retval);
}

VOID
spinner(VOID)                      /* display a little spinner if busy     */
{
     static CHAR *blade=" /-\\|";
     static UINT numstep,oldtck=0;
     INT tmr;

     if ((tmr=btuTicker()) != oldtck) {
          numstep=0;
          oldtck=tmr;
     }
     if (numstep++ < 10) {
          if (flo->prop++ > 0) {
               prf("");
          }
          if (flo->prop >= strlen(blade)) {
               flo->prop=1;
          }
          prf("%c",blade[flo->prop]);
          outprf(usrnum);
          prf("");
     }
}

VOID
locsysfl(                          /* locate a file for the sysop or libop */
CHAR *filname)
{
     CHAR libname[FLNAMESZ];
     struct fllib *libptr;
     INT ctr=0;

     setmem(libname,FLNAMESZ,0);
     dfaSetBlk(flfdat);
     setmbk(flmsg);
     prfmsg(SYSFILES);
     while (dfaAcqGT(NULL,rcompkey(libname,filname),COMPFL)
        && sameas(flf->filname,filname)) {
          stzcpy(libname,flf->libname,FLNAMESZ);
          if ((libptr=libfind(libname)) != NULL && isflop(libptr)) {
               prf("%s ",libname);
               ctr++;
          }
     }
     if (ctr == 0) {
          clrprf();
          prfmsg(NOFILIB);
     }
     else {
          prfmsg(SUMFILES);
     }
     rstmbk();
}

VOID
notidl(VOID)                       /* notify user of files to d/l          */
{
     switch (uwaitcpy(usrnum)) {
     case 0:
          if (totags > 0) {
               prfmsg(NOTDLNW);
          }
          break;
     case 1:
          prfmsg(NOTDLWT);
     }
}

INT
notapped(                           /* is file unapproved?                 */
const CHAR *udate)
{
     return(udate[0] == '\0' || sameas(udate,NOTAPPED));
}

LONG
libroom(                           /* how much room for an upload?         */
struct fllib *libptr)
{
     if (libptr->flags&FLGDOS) {
          cntdir(spr("%s"SLS STAR,libpath(libptr)));
     }
     else {
          numfils=libptr->numfiles;
          numbytp=libptr->totbytes;
     }
     byteroom=min(libptr->maxbup,libptr->maxbyt-numbytp);
     return(libptr->maxfil-numfils);
}

CHAR *
libpath(                           /* return path to lib's files           */
struct fllib *libptr)
{
     return(libptr->path[0] != '\0' ? fixpath(libptr->path) : libptr->libname);
}

INT
haslibkey(                         /* user has certain access to Library   */
struct fllib *libptr,              /* ... Library concerned                */
CHAR *keyname)                     /* ... key name to check for            */
{
     return(libptr != NULL                        /* library exists        */
         && (isflop(libptr)                       /* and user is Lib-OP    */
          || (!sameto("_LIBOP",keyname)           /* or the key is valid   */
           && uhskey(usaptr->userid,keyname))));  /* and the user has it   */
}

INT
usrupd(                            /* user has access to modify u/l'd file */
struct fllib *libptr,
CHAR *filname)
{
     struct taglib *tag;
     INT retval=0,loop;

     dfaSetBlk(flfdat);
     if (dfaAcqEQ(NULL,compkey(libptr->libname,filname),COMPLF)) {
          if (ucanovw(libptr,flf)) {
               retval=1;
               for (loop=0 ; loop < systags ; loop++) {
                    tag=tagoff(loop);
                    if (tag->status > TGEMPTY && tag->usrnum != usrnum
                       && sameas(tag->filname,filname)
                       && sameas(tag->libname,libptr->libname)) {
                         retval=2;
                    }
               }
          }
          if (w2writ(libptr->libname,filname,0) != NOCONFLICT) {
               retval=2;
          }
     }
     else {
          retval=-1;
     }
     dfaRstBlk();
     return(retval);
}

VOID
chkjoin(VOID)                      /* check all Libraries' joined status   */
{
     struct fllib *libptr;
     INT loop,loop2;
     CHAR *lib;

     for (loop=0 ; loop < numoflib ; loop++) {
          libptr=liboff(loop);
          if (libptr != NULL) {
               for (loop2=0 ; loop2 < FLNMCATS ; loop2++) {
                    lib=libptr->cat[loop2];
                    if (lib[0] != '\0' && libfind(lib) == NULL) {
                         lib[0]='\0';
                         movmem(libptr->cat[loop2+1],lib,
                            (FLNMCATS-loop2-1)*FLNAMESZ);
                         libptr->cat[FLNMCATS-1][0]='\0';
                         libptr->flags|=LIBCHN;
                    }
               }
          }
     }
}

INT
totnlibs(                          /* return # of libraries joined+1, or   */
CHAR *libname,                     /* the index of the library number      */
INT index)                         /* == -1 if total # is wanted           */
{
     INT loop,libs=0;
     struct fllib *libptr;

     for (loop=0 ; loop < numoflib ; loop++) {
          libptr=liboff(loop);
          if (strlen(visxlib(libptr,libname)) != 0) {
               if (index == libs++) {
                    return(loop);
               }
          }
     }
     return(libs);
}

GBOOL
initsrc(VOID)                      /* init. join or multi. lib search      */
{                                  /* returns 1 if speed search is it      */
     INT tl;
     struct fllib *libptr=NULL;
     CHAR *libname="*";

     srcoff();
     srcu->nlibs=0;
     switch (flo->keymeth) {
     case 3:
          libname=flo->u.key3.libname;
          break;
     case 4:
     case 7:
     case 8:
          libname=flo->u.key4.libname;
          break;
     }
     if (libname[0] != '*') {
          if (libname[0] != '\0') {
               libptr=libfind(libname);
          }
          if ((libptr != NULL || libname[0] == '\0')
             && (tl=totnlibs(libname,-1)) <= maxjoin && tl > 1) {
               srcu->nlibs=tl;
               srcu->nloaded=0;
               flo->flags&=~REVSRCH;
               return(1);
          }
     }
     return(0);
}

GBOOL
ccycidx(VOID)                      /* cycle index building                 */
{
     union srch *next,*prev;
     struct fllib *libptr=NULL;

     srcoff();
     next=&srcu->tn[srcu->nloaded];
     setmem(next,sizeof(union srch),0);
     prev=&srcu->tp[srcu->nloaded];
     setmem(prev,sizeof(union srch),0);
     dfaSetBlk(flfdat);
     switch (flo->keymeth) {
     case 3:
          libptr=liboff(totnlibs(flo->u.key3.libname,srcu->nloaded));
          if (libptr != NULL) {
               stzcpy(next->key0.libname,libptr->libname,FLNAMESZ);
               stzcpy(next->key0.filname,flo->u.key3.filname,FLFILENM);
               stzcpy(next->key0.udate,flo->u.key3.udate,DATESZ);
               stzcpy(prev->key0.libname,libptr->libname,FLNAMESZ);
               stzcpy(prev->key0.filname,flo->u.key3.filname,FLFILENM);
               stzcpy(prev->key0.udate,flo->u.key3.udate,DATESZ);
               if (dfaAcqGE(NULL,&next->key0,COMPLUF)
                  && sameas(flf->libname,next->key0.libname)) {
                    stzcpy(next->key0.filname,flf->filname,FLFILENM);
                    stzcpy(next->key0.udate,flf->udate,DATESZ);
               }
               else {
                    next->key0.udate[0]=0xFF;
               }
               if (prev->key0.udate[0] != 0x00
                  && dfaAcqLT(NULL,&prev->key0,COMPLUF)
                  && sameas(flf->libname,prev->key0.libname)) {
                    stzcpy(prev->key0.filname,flf->filname,FLFILENM);
                    stzcpy(prev->key0.udate,flf->udate,DATESZ);
               }
               else {
                    prev->key0.udate[0]=0x00;
               }
               prev=&srcu->fp[srcu->nloaded];
               movmem(next,prev,sizeof(union srch));
          }
          break;
     case 4:
     case 7:
     case 8:
          libptr=liboff(totnlibs(flo->u.key4.libname,srcu->nloaded));
          if (libptr != NULL) {
               stzcpy(next->key1.libname,libptr->libname,FLNAMESZ);
               stzcpy(next->key1.filname,flo->u.key4.filname,FLFILENM);
               stzcpy(prev->key1.libname,libptr->libname,FLNAMESZ);
               stzcpy(prev->key1.filname,flo->u.key4.filname,FLFILENM);
               if (dfaAcqGE(NULL,&next->key1,COMPLF)
             && sameas(flf->libname,next->key1.libname)) {
                    stzcpy(next->key1.filname,flf->filname,FLFILENM);
               }
               else {
                    next->key1.filname[0]=0xFF;
               }
               if (prev->key1.filname[0] != 0x00
             && dfaAcqLT(NULL,&prev->key1,COMPLF)
             && sameas(flf->libname,prev->key1.libname)) {
                    stzcpy(prev->key1.filname,flf->filname,FLFILENM);
               }
               else {
                    prev->key1.filname[0]=0x00;
               }
               prev=&srcu->fp[srcu->nloaded];
               movmem(next,prev,sizeof(union srch));
          }
          break;
     }
     if (libptr == NULL) {
          srcu->nlibs=srcu->nloaded;
          return(FALSE);
     }
     if (++srcu->nloaded == srcu->nlibs) {
          return(FALSE);
     }
     return(TRUE);
}

VOID
newpage(VOID)                      /* ready the keysets for a new page     */
{
     srcoff();
     if (!(flo->flags&REVSRCH)) {
          movmem(srcu->fn,srcu->tp,srcu->nlibs*sizeof(union srch));
          movmem(srcu->tn,srcu->fp,srcu->nlibs*sizeof(union srch));
     }
     else {
          movmem(srcu->tp,srcu->fn,srcu->nlibs*sizeof(union srch));
          movmem(srcu->fp,srcu->tn,srcu->nlibs*sizeof(union srch));
     }
}

VOID
cycinp(VOID)
{
     INT c=0;

     setmem(input,2,0);
     if (btuibw(usrnum) == 0) {
          actdet=0;
     }
     while (c == 0 && btuica(usrnum,input,1) > 0) {
          c=toupper(*input);
          if (!isalnum(c)) {
               switch (c) {
               case 14:
                    c='+';
                    break;
               case 16:
                    c='-';
                    break;
               case '?':
                    break;
               case 23:
               case ' ':
                    c='@';
                    break;
               case 4:
                    c='%';
                    break;
               case 9:
                    c='>';
                    break;
               case 22:
                    c='&';
                    break;
               case 20:
                    c='#';
                    break;
               case 13:
                    c='!';
                    break;
               case 27:
                    arrower[usrnum]=1;
                    c=0;
                    break;
               case '[':
                    arrower[usrnum]=(arrower[usrnum] == 1 ? 2 : 0);
                    c=0;
                    break;
               default:
                    c=0;
                    arrower[usrnum]=0;
               }
          }
          if (c > 0) {
               if (arrower[usrnum] == 2) {
                    switch (c) {
                    case 'A':
                    case 'D':
                         c='<';
                         break;
                    case 'B':
                    case 'C':
                         c='>';
                         break;
                    case 'H':
                         c='(';
                         break;
                    case 'K':
                         c=')';
                         break;
                    default:
                         c=0;
                    }
               }
               if (c > 0) {
                    input[0]=c;
                    inplen=1;
                    parsin();
                    if (lsinp() == 0) {
                         btuclo(usrnum);
                         btupbc(usrnum,0);
                         prfmsg(CLRSCN);
                         rstrxf();
                         btutsw(usrnum,usaptr->scnwid);
                         echonu(usrnum);
                         btutrg(usrnum,0);
                         if ((flo->flags&USRANSI) && !(flo->flags&UNOINJO)) {
                              usrptr->flags&=~NOINJO;
                         }
                         outprf(usrnum);
                         usrptr->substt=MMENU;
                         injacr();
                         return;
                    }
               }
               arrower[usrnum]=0;
          }
     }
}
