/***************************************************************************
 *                                                                         *
 *   GALFILUT.C                                                            *
 *                                                                         *
 *   Copyright (c) 1993-1997 Galacticomm, Inc.    All Rights Reserved.     *
 *                                                                         *
 *   File Libraries - Utility Routines                                     *
 *                                                                         *
 *                                                 - D. Pitchford  9/28/93 *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "majorbbs.h"
#include "gcspsrv.h"
#include "galfil.h"
#include "filexfer.h"
#include "fsdbbs.h"
#include "reserve.h"
#include "galfilh.h"

#define FILREV "$Revision: 20 $"

CHAR *
checkdir(                          /* modify path to proper format         */
CHAR *path)                        /* ... i.e., no trailing \ or /         */
{
     INT len;
     CHAR chr,*sptr;

     if ((sptr=strchr(path,':')) != NULL) {
          if (sptr-path != 1) {
               *path='\0';
          }
          else {
               if (!isalpha(*path)) {
                    *path='\0';
               }
               else if ((sptr=strchr(++sptr,':')) != NULL) {
                    *sptr='\0';
               }
          }
     }
     len=strlen(path);
     while (len > 0) {
          chr=path[len-1];
          if (chr == '\\' || chr == '/') {
               if (path[len-2] == ':') {
                    strcat(path,".");
                    break;
               }
               else {
                    path[--len]='\0';
               }
          }
          else {
               if (chr == ':') {
                    strcat(path,".");
               }
               break;
          }
     }
     return(path);
}

CHAR *
fixpath(                           /* return a properly formatted path     */
CHAR *path)
{
     static CHAR retval[4][GCMAXPTH];
     static INT cycle=0;

     return(checkdir(stzcpy(retval[cycle=((cycle+1)&3)],strlwr(path),GCMAXPTH)));
}

CHAR *
compkey(                           /* build a composite key (struct key1)  */
const CHAR *libname,
const CHAR *filname)
{
     static CHAR key[FLNAMESZ+FLFILENM];

     stzcpy(key,libname,FLNAMESZ);
     stzcpy(&key[FLNAMESZ],filname,FLFILENM);
     return(key);
}

CHAR *
rcompkey(                          /* build a composite key (struct key4)  */
const CHAR *libname,
const CHAR *filname)
{
     static CHAR key[FLNAMESZ+FLFILENM];

     stzcpy(key,filname,FLFILENM);
     stzcpy(&key[FLFILENM],libname,FLNAMESZ);
     return(key);
}

CHAR *
cutpunc(                           /* cuts words at punctuation            */
CHAR *stg)
{
     CHAR *cptr;

     for (cptr=stg ; *cptr != '\0' ; cptr++) {
          if (!isalnum(*cptr) && *cptr < 128) {  /* keep high-ASCII foreign */
               *cptr='\0';
               if ((++cptr)[0] != '\0' && (dargc < (MAXKWDS-1))) {
                    dargv[dargc++]=cptr;
               }
               break;
          }
     }
     return(stg);
}

CHAR *
dat2srtu(                          /* convert 10/24/1993 to "1070207"      */
INT year,                          /* 2100-1993==107, 12-10==02, 31-24==07 */
INT month,
INT day)
{
     static CHAR retval[4][DATESZ];
     static INT cycle=0;

     memset(retval[cycle=((cycle+1)&3)],0,DATESZ);
     if (year <= 2100 && validDate(year,month,day)) {
          sprintf(retval[cycle],"%03d%02d%02d",2100-year,12-month,31-day);
     }
     else {
          strcpy(retval[cycle],NOTAPPED);
     }
     return(retval[cycle]);
}

CHAR *
dat2srt(                           /* convert "10/24/[19]93" to "1070207"  */
const CHAR *dt)                    /* 2100-1993==107, 12-10==02, 31-24==07 */
{
     INT y,m,d;

     dateDecode(dt,&y,&m,&d);
     return(dat2srtu(y,m,d));
}

CHAR *
ddat2srt(                          /* convert DOS date to "1070207"        */
USHORT dosDate)
{
     return(dat2srtu(ddyear(dosDate),ddmon(dosDate),ddday(dosDate)));
}

LONG
dnlchg(                            /* approx d/l charge                    */
LONG siz,
CHAR *libname)
{
     struct fllib *libptr;
     LONG estcreds=0L,price;

     if (libname[0] == '\0' || ((libptr=libfind(libname)) == NULL)) {
          return(0L);
     }
     if (!(fndcls(usaptr->curcls)->flags&CRDXMT)) {
          estcreds=((dnlsecl(siz,libptr)/15L)+1)*(lincst(usrnum)+
                    (LONG)(usrptr->crdrat/4));
     }
     price=dnlprc(siz,libptr);
     if (price == 0L) {
          estcreds=0L;
     }
     return(price+estcreds);
}

CHAR *
dnlmin(                            /* approx mins. to d/l                  */
LONG siz)
{
     static CHAR c[11];
     LONG x;

     setmem(c,11,0);
     x=dnlsec(siz);
     if (x < 45L) {
          return("< 1");
     }
     else {
          sprintf(c,"%ld",(x+30L)/60L);
     }
     return(c);
}

CHAR *
fzer(                              /* returns l2as(number) or "< 1" if 0   */
LONG num)
{
     return(num == 0L ? "< 1" : l2as(num));
}

CHAR *
protocol(VOID)                     /* return protocol to use               */
{
     return(flu->proto[0] != '\0'
        ? ((flo->flags&ABOUPRF) ? "?" : flu->proto) : defproto);
}

static VOID
srt2ymd(                           /* convert "1070207" to 1993, 10, 24    */
const CHAR *dt,                    /*   source date string                 */
INT *pYear,                        /*   buffer for year                    */
INT *pMonth,                       /*   buffer for month                   */
INT *pDay)                         /*   buffer for day                     */
{
     CHAR buf[4];

     ASSERT(dt != NULL);
     ASSERT(strlen(dt) == CSTRLEN("1070207"));
     ASSERT(pYear != NULL);
     ASSERT(pMonth != NULL);
     ASSERT(pDay != NULL);
     buf[0]=dt[0];
     buf[1]=dt[1];
     buf[2]=dt[2];
     buf[3]='\0';
     *pYear=2100-atoi(buf);
     buf[0]=dt[3];
     buf[1]=dt[4];
     buf[2]='\0';
     *pMonth=12-atoi(buf);
     buf[0]=dt[5];
     buf[1]=dt[6];
     buf[2]='\0';
     *pDay=31-atoi(buf);
}

static CHAR *
srt2datu(                          /* convert "1070207" to "10/24/1993"    */
const CHAR *dt,                    /*   date string to convert             */
INT mode)                          /*   prnDate mode to use for output     */
{
     INT y,m,d;
     static CHAR retval[4][LDATSIZ];
     static INT cycle=0;

     ASSERT(dt != NULL);
     ASSERT(mode == PRND_MDYY || mode == PRND_MDY);
     memset(retval[cycle=((cycle+1)&3)],0,LDATSIZ);
     if (strlen(dt) == 7) {
          srt2ymd(dt,&y,&m,&d);
          prnDate(y,m,d,retval[cycle],LDATSIZ,mode,'/');
     }
     return(retval[cycle]);
}

CHAR *
srt2dat(                           /* convert "1070207" to "10/24/93"      */
const CHAR *dt)
{
     return(srt2datu(dt,PRND_MDY));
}

CHAR *
srt2datl(                          /* convert "1070207" to "10/24/1993"    */
const CHAR *dt)
{
     return(srt2datu(dt,PRND_MDYY));
}

CHAR *
tvcomeff(VOID)                     /* returns communications efficiency    */
{
     static CHAR retval[4];

     sprintf(retval,"%d",comeff);
     return(retval);
}

CHAR *
tvctim(VOID)                       /* return creation time & date          */
{
     return(curlib == NULL ? "" : spr("%s %s",ncdate(curlib->day),
                                              nctime(curlib->time)));
}

CHAR *
tvctiml(VOID)                      /* return long creation time & date     */
{
     return(curlib == NULL ? "" : spr("%s %s",ncdatel(curlib->day),
                                              nctime(curlib->time)));
}

CHAR *
tvdesc(VOID)                       /* return current Library description   */
{
     return(curlib == NULL ? "" : curlib->libdesc);
}

CHAR *
tvdesc0(VOID)                      /* return part of long description      */
{
     static CHAR rv[164];

     loadldsc(NULL);
     if (libupd->ldesc[0][0] == '\0') {
          return("");
     }
     sprintf(rv,"%s\r",libupd->ldesc[0]);
     return(rv);
}

CHAR *
tvdesc1(VOID)                      /* return part of long description      */
{
     static CHAR rv[162];

     if (libupd->ldesc[1][0] == '\0') {
          return("");
     }
     sprintf(rv,"%s\r",libupd->ldesc[1]);
     return(rv);
}

CHAR *
tvdesc2(VOID)                      /* return part of long description      */
{
     static CHAR rv[162];

     if (libupd->ldesc[2][0] == '\0') {
          return("");
     }
     sprintf(rv,"%s\r",libupd->ldesc[2]);
     return(rv);
}

CHAR *
tvdesc3(VOID)                      /* return part of long description      */
{
     static CHAR rv[162];

     if (libupd->ldesc[3][0] == '\0') {
          return("");
     }
     sprintf(rv,"%s\r",libupd->ldesc[3]);
     return(rv);
}

CHAR *
tvdesc4(VOID)                      /* return part of long description      */
{
     static CHAR rv[162];

     if (libupd->ldesc[4][0] == '\0') {
          return("");
     }
     sprintf(rv,"%s\r",libupd->ldesc[4]);
     return(rv);
}

CHAR *
tvdnlmin(VOID)                     /* return est. minutes to d/l           */
{
     return(skpwht(dnlmin(flf->siz)));
}

CHAR *
tvfapp(VOID)                       /* return current Library files to app  */
{
     static CHAR retval[7];

     if (curlib == NULL) {
          return("");
     }
     sprintf(retval,"%d",(curlib->appwait < 0) ? 0 : curlib->appwait);
     return(retval);
}

CHAR *
tvfdate(VOID)                      /* return dos date or "UNAPPROVED"      */
{
     return(notapped(flf->udate) ? "UNAPPRVD" : srt2dat(flf->fdate));
}

CHAR *
tvfdates(VOID)                     /* return short dos date or "UNAPP"     */
{
     static CHAR retval[6];
     CHAR *stg;

     if (notapped(flf->udate)) {
          strcpy(retval,"UNAPP");
     }
     else {
          stg=srt2dat(flf->fdate);
          setmem(retval,6,0);
          retval[0]=stg[0];
          retval[1]=stg[1];
          retval[2]='/';
          retval[3]=stg[6];
          retval[4]=stg[7];
     }
     return(retval);
}

CHAR *
tvfdatel(VOID)                     /* return dos date or "UNAPPROVED"      */
{
     return(notapped(flf->udate) ? "UNAPPROVED" : srt2datl(flf->fdate));
}

CHAR *
tvfname(VOID)                      /* return filename                      */
{
     return(flf->filname);
}

CHAR *
tvflib(VOID)                       /* return libname                       */
{
     struct fllib *libptr;

     libptr=libfind(flf->libname);
     return(libptr != NULL ? visxlib(libptr,"") : "");
}

CHAR *
tvfnum(VOID)                       /* return current Library # of files    */
{
     static CHAR retval[15];
     LONG nfiles;

     if (curlib == NULL) {
          return("");
     }
     if (curlib->flags&FLGDOS) {
          return("OS");
     }
     if (curlib->libs > 0) {       /* if a top-level lib, get the totals   */
          scanlib(1,curlib);
          nfiles=curlib->totfiles;
          scanlib(0,curlib);
     }
     else {
          nfiles=curlib->numfiles-curlib->appwait;
     }
     if (nfiles < 0L || nfiles > 999999L) {
          nfiles=0L;
     }
     sprintf(retval,"%ld",nfiles);
     return(retval);
}

CHAR *
tvfsize(VOID)                      /* return file size                     */
{
     return(l2as(flf->siz));
}

CHAR *
filsize(                           /* return passed file size 5-byte fmt.  */
LONG size,                         /* size for the file                    */
LONG kval)                         /* value for "K" and "M", 1000/1024     */
{
     static CHAR rsize[6];
     LONG ksiz;

     if (kval != 1000L) {
          kval=1024L;
     }
     if (size < kval) {
          sprintf(rsize,"%5ld",size);
     }
     else {
          ksiz=size/kval;
          if (ksiz >= kval) {
               if (ksiz >= 100L*kval) {
                    sprintf(rsize,"%4ldM",ksiz/kval);
               }
               else {
                    sprintf(rsize,"%2ld.%1ldM",ksiz/kval,10L*(ksiz%kval)/kval);
               }
          }
          else {
               if (ksiz >= 10L) {
                    sprintf(rsize,"%4ldK",ksiz);
               }
               else {
                    sprintf(rsize,"%2ld.%1ldK",ksiz,10L*(size%kval)/kval);
               }
          }
     }
     return(rsize);
}

CHAR *
tvfsizek(VOID)                     /* return file size                     */
{
     return(filsize(flf->siz,1024L));
}

CHAR *
tvftimes(VOID)                     /* return # of times downloaded         */
{
     return(l2as(atol(flf->numdls)));
}

CHAR *
tvfulby(VOID)                      /* return name of uploader              */
{
     return(flf->ulby);
}

CHAR *
tvinit(VOID)                       /* if using FL_ tvars on a menu page,   */
{                                  /* call this one first to initialize    */
     fluoff(usrnum);               /* for the user                         */
     setftu();
     return("");
}

CHAR *
tvmisc(VOID)                       /* handy misc variable, instead of a %s */
{
     return(flmisc);
}

CHAR *
tvname(VOID)                       /* return name of current Library       */
{
     return(curlib == NULL ? "" : curlib->libname);
}

CHAR *
tvtagk(VOID)                       /* return current tag file character    */
{
     static CHAR retval[2];

     retval[0]=flo->tagk;
     retval[1]='\0';
     return(retval);
}

CHAR *
tagk(VOID)                         /* return tag letter reference          */
{
     static CHAR retval[200];
     CHAR *stg;

     setmem(retval,200,0);
     setmbk(flmsg);
     if (strlen(stg=getmsg(flo->tagk == 'A' ? TAGKONE : TAGKMANY)) < 200) {
          sprintf(retval,stg,flo->tagk);
     }
     rstmbk();
     return(retval);
}

CHAR *
tvtags(VOID)                       /* return # of tags (-1)                */
{
     static CHAR nt[5];

     setftu();
     sprintf(nt,"%d",totags);
     return(nt);
}

CHAR *
tvtshmsg(VOID)                     /* return file xfer facility's message  */
{
     return(tshmsg);
}

CHAR *
tvudate(VOID)                      /* return u/l date or "UNAPPRVD"        */
{
     return(notapped(flf->udate) ? "UNAPPRVD" : srt2dat(flf->udate));
}

CHAR *
tvudatel(VOID)                     /* return long u/l date or "UNAPPROVED" */
{
     return(notapped(flf->udate) ? "UNAPPROVED" : srt2datl(flf->udate));
}

CHAR *
tvbytu(VOID)                       /* return max upload size               */
{
     return(curlib == NULL ? "" : l2as(curlib->maxbup));
}

CHAR *
tvbytt(VOID)                       /* return max Library size              */
{
     return(curlib == NULL ? "" : l2as(curlib->maxbyt));
}

CHAR *
tvbyto(VOID)                       /* return max u/l size                  */
{
     if (curlib == NULL) {
          return("");
     }
     libroom(curlib);
     return(l2as(byteroom > 0L ? byteroom : 0L));
}

CHAR *
tvfilt(VOID)                       /* return max Library # files           */
{
     return(curlib == NULL ? "" : l2as(curlib->maxfil));
}

INT
alrtag(                            /* user already tagged file??           */
CHAR *libname,
CHAR *filname)
{
     struct taglib *tag;
     INT loop,loop2;

     for (loop=0 ; loop < systags ; loop++) { /* see if usr already tagged */
          tag=tagoff(loop);
          if (tag->status > TGEMPTY && sameas(tag->filname,filname)
           && tag->usrnum == usrnum && sameas(tag->libname,libname)) {
               setftu();
               for (loop2=0 ; loop2 < ftuptr->numftg ; loop2++) {
                    ftgptr=&ftgusr[loop2];
                    if (spc == tag) {
                         return(loop+1);
                    }
               }
          }
     }
     return(0);
}

INT
amrlib(                            /* Library contributions to amreading() */
CHAR *grp,                         /* group name (e.g. Library name)       */
CHAR *fil)                         /* file name (or "*"=any file in group) */
{                                  /* returns NOCONFLICT=nobody, else=who  */
     struct taglib *tag;
     INT loop;

     if (sameas(fil,"*")) {
          for (loop=0 ; loop < systags ; loop++) {
               tag=tagoff(loop);
               if (tag->status > TGEMPTY && sameas(tag->libname,grp)) {
                    return(tag->usrnum);
               }
          }
     }
     else {
          for (loop=0 ; loop < systags ; loop++) {
               tag=tagoff(loop);
               if (tag->status > TGEMPTY && sameas(tag->libname,grp)
                                         && sameas(tag->filname,fil)) {
                    return(tag->usrnum);
               }
          }
     }
     return(NOCONFLICT);
}

INT
countc(                            /* count # of certain characters in stg */
CHAR *stg,
CHAR chr)
{
     INT retval=0;

     while (*stg != '\0') {
          if (*stg++ == chr) {
               retval++;
          }
     }
     return(retval);
}

INT
deparse(                           /* reduces and/or/not primitive to y/n  */
CHAR *p)                           /* *p is the primitive, (!0&(0|!(1^0))) */
{
     CHAR image[FLKEYLST];

     while (strlen(p) > 1) {
          stzcpy(image,p,FLKEYLST);
          do {
               do {
                    do {
                         do {
                              do {
                              } while (strsrep(p,"(1)","1")
                                 || strsrep(p,"(0)","0"));
                         } while (strsrep(p,"!1","0") || strsrep(p,"!0","1"));
                    } while (strsrep(p,"1&1","1") || strsrep(p,"1&0","0")
                       || strsrep(p,"0&1","0") || strsrep(p,"0&0","0"));
               } while (strsrep(p,"1^1","0") || strsrep(p,"1^0","1")
                  || strsrep(p,"0^1","1") || strsrep(p,"0^0","0"));
          } while (strsrep(p,"1|1","1") || strsrep(p,"1|0","1")
             || strsrep(p,"0|1","1") || strsrep(p,"0|0","0"));
          if ((!countc(p,'1') && !countc(p,'0')) || sameas(image,p)) {
               return(0);
          }
     }
     return(sameas(p,"1") ? 1 : -1);
}

INT
dotags(                            /* decide what files a user has tagged  */
INT quiet)
{
     INT loop,tot=0;

     for (loop=0 ; loop < NLISTER ; loop++) {
          if (flo->tdline[loop] < 0) {
               tot+=submit(flo->tags[loop].libname,flo->tags[loop].filname,
                  flo->lrange,NOTVIEW,quiet);
          }
     }
     flo->tagcnt=0;
     setfull(totags >= (maxtags-1));
     return(tot);
}

VOID
setfull(                           /* set users' full tag flag on or off   */
INT isfull)
{
     if (isfull) {
          flo->flags|=FULLTAG;
     }
     else {
          flo->flags&=~FULLTAG;
     }
}

INT
findbest(                          /* find oldest task of type stt         */
INT stt)                           /*   sets ftag to best tag spec,        */
{                                  /*   leaves NULL if best is c/s, and    */
     INT retval=0,loop,i;          /*   returns usrnum+1                   */
     struct taglib *filetag;

     ftag=NULL;
     for (loop=0 ; loop < systags ; loop++) {
          filetag=tagoff(loop);
          if (filetag->status == stt) {
               if (!retval || ftag->tagtime > filetag->tagtime) {
                    retval=1;
                    ftag=filetag;
               }
          }
     }
     switch (stt) {
     case TGCOPY:
     case TGINWAIT:
          i=csfbest(stt,ftag == NULL ? -1L : ftag->tagtime);
          if (i != -1) {
               retval=i+1;
               ftag=NULL;
          }
     }
     return(retval);
}

INT
visilib(                           /* is libptr visible to current user?   */
struct fllib *libptr)              /* always visible to libops/sysops      */
{
     return((haskey(libptr->keyreq) && !(libptr->flags&FLGHID))
         || isflop(libptr));
}

CHAR *
visxlib(                           /* is libptr visible even indirectly?   */
struct fllib *libptr,
CHAR *libmatch)                    /* ... if specified, also joined        */
{
     INT loop;
     struct fllib *libcat;

     if (visilib(libptr)) {
          if (libmatch[0] == '\0' || sameas(libmatch,libptr->libname)) {
               return(libptr->libname);
          }
     }
     if (!haslibkey(libptr,libptr->keyreq)) {
          return("");
     }
     for (loop=0 ; loop < FLNMCATS ; loop++) {
          if (libptr->cat[loop][0] != '\0'
           && (libcat=libfind(libptr->cat[loop])) != NULL
           && visilib(libcat)) {
               if (libmatch[0] == '\0' || sameas(libmatch,libcat->libname)) {
                    return(libcat->libname);
               }
          }
     }
     return("");
}

INT
keyfig(VOID)                       /* apply primitive template to file     */
{
     INT loop;
     CHAR blist[FLKEYLST];

     if (!makwdlst(flf->desc,flf->filname)) {
          return(-1);
     }
     stzcpy(blist,flo->keylist,FLKEYLST);
     for (loop=0 ; loop < flo->kcount ; loop++) {
          if (!strsrep(blist,"?",keyin(&vdaptr[loop*FLKEYSIZ]) ? "1" : "0" )) {
               return(-1);
          }
     }
     return(deparse(blist));
}

INT
keyin(                             /* is keyword in keylist?               */
CHAR *key)
{
     INT loop,len;
     CHAR *filname;

     filname=spr("%s",flf->filname);
     strcrep(filname,'.','\0');
     len=strlen(flf->desc)-strlen(key);
     for (loop=0 ; loop <= len ; loop++) {
          if (sameto(key,&flf->desc[loop])) {
               return(1);
          }
     }
     len=strlen(filname)-strlen(key);
     for (loop=0 ; loop <= len ; loop++) {
          if (sameto(key,&filname[loop])) {
               return(1);
          }
     }
     return(0);
}

INT
keysin(                            /* make key list and determine keyword  */
INT start)
{
     INT loop;

     if (!makwdlst(flf->desc,flf->filname)) {
          return(-1);
     }
     for (loop=0 ; loop < flo->kcount ; loop++) {
          if ((loop != start) && !keyin(&vdaptr[loop*FLKEYSIZ])) {
               return(-1);
          }
     }
     return(1);
}

INT
kwdout(VOID)                       /* make kwd list and ready for insert   */
{
     if (!makwdlst(flf->desc,flf->filname)) {
          return(0);
     }
     prfmsg(usrptr->substt=KEYWORDY);
     stzcpy(flo->kwdy.filname,flf->filname,FLFILENM);
     stzcpy(flo->kwdy.libkey,flf->libname,FLNAMESZ);
     flo->miscflag=-1;
     btuinj(usrnum,CYCLE);
     return(1);
}

INT
nlibtagd(VOID)                     /* # of Library files tagged            */
{
     INT loop,retval=0;

     for (loop=0 ; loop < ftuptr->numftg ; loop++) {
          ftgptr=&ftgusr[loop];
          fltagf=0;
          ftgptr->tshndl(TSHDSC);
          if (fltagf) {
               retval++;
          }
     }
     setmbk(flmsg);
     return(retval);
}

INT
okfname(                           /* make sure passed file name is ok     */
const CHAR *filename)
{
     INT loop=0,len,dot=0;

     if (!(len=strlen(filename)) || len > 12) {
          return(0);
     }
     if (len > 8) {
          do {
               if (filename[loop] == '.') {
                    if (loop == 0 || loop < (len-4)) {
                         return(0);
                    }
                    break;
               }
               if (++loop > 8) {
                    return(0);
               }
          } while (1);
     }
     if (rsvnam(filename) || profane(filename)) {
          return(0);
     }
     for (loop=0 ; loop < len ; loop++,filename++) {
          switch (*filename) {
          case '.':
               if ((!dot++) && (loop >= (len-4)) && loop) {
                    break;
               }
          case '\\':
          case ':':
          case '/':
          case '*':
          case '?':
          case '+':
          case '<':
          case '>':
               return(0);
          default:
               if (*filename <= ' ') {
                    return(0);
               }
          }
     }
     return(1);
}

INT
readline(                          /* read a line from a text file         */
FILE *ptr)
{
     static INT last=0;
     INT chr=0,retval=1;
     CHAR *pos;

     setmem(input,INPSIZ,0);
     pos=input;
     while (chr != 13 && chr != 10 && ptr != NULL) {
          chr=fgetc(ptr);
          if (feof(ptr) || ferror(ptr)) {
               last=0;
               retval=0;
               rewind(ptr);
               chr=13;
          }
          else {
               switch (chr) {
               case 10:
               case 13:
                    if (!last) {
                         last=1;
                    }
                    else {
                         if (input[0] == '\0') {
                              chr=0;
                         }
                         last=0;
                    }
                    break;
               case 0:
                    chr=13;
                    break;
               case 26:
               case EOF:
                    break;
               default:
                    last=0;
                    *pos=chr;
                    pos++;
                    if (strlen(input) == INPSIZ-1) {
                         chr=13;
                    }
               }
          }
     }
     return(retval);
}

INT
srch1(VOID)                        /* sysop search cycle for file checks   */
{
     struct fllib *libptr;

     dfaSetBlk(flfdat);
     if (dfaAcqGT(NULL,&flo->key1,COMPLF)) {
          if (flo->misclib[0] != '\0' && !sameas(flf->libname,flo->misclib)) {
               return(0);
          }
          stzcpy(flo->key1.libname,flf->libname,FLNAMESZ);
          stzcpy(flo->key1.filname,flf->filname,FLFILENM);
          if ((libptr=libfind(flf->libname)) != NULL
           && !(libptr->flags&FLGDOS)
           && (!(libptr->flags&FLGCBD) || libptr->path[0] != '\0')) {
               if (fndfile(&flo->fb,
                           spr("%s"SLS"%s",libpath(libptr),flf->filname),0)) {
                    if (flo->fb.ff_fsize != flf->siz) {
                         if (dfaAcqEQ(NULL,&flo->key1,COMPLF)) {
                              flf->siz=flo->fb.ff_fsize;
                              dfaUpdateV(NULL,FLFILREC+strlen(flf->desc)+1);
                         }
                         prfmsg(NOSIZEM,flf->filname,libptr->libname);
                         if (usrptr->flags&ISGCSU) {
                              sendres(unpad(stp4cs(prfbuf)));
                         }
                         else {
                              outprf(usrnum);
                         }
                    }
               }
               else {
                    if (flo->miscflag < 0 && dfaAcqEQ(NULL,&flo->key1,COMPLF)) {
                         if (!notapped(flf->udate)) {
                              libptr->appwait++;
                         }
                         chuldate(libptr,flf->udate,0);
                         libptr->flags|=LIBCHN;
                         stzcpy(flf->udate,NOTAPPED,DATESZ);
                         dfaUpdateV(NULL,FLFILREC+strlen(flf->desc)+1);
                    }
                    prfmsg(NOFILEPR,flf->filname,libptr->libname,
                           (flo->miscflag < 0) ? "; unapproved" : "");
                    if (usrptr->flags&ISGCSU) {
                         sendres(unpad(stp4cs(prfbuf)));
                    }
                    else {
                         outprf(usrnum);
                    }
               }
          }
          return(1);
     }
     return(0);
}

INT
srch2(VOID)                        /* sysop search cycle for file checks   */
{
     struct fllib *libptr;
     CHAR *lib;

     dfaSetBlk(flfdat);
     lib=flo->key1.libname;
     if (lib[0] != '\0' && (libptr=libfind(lib)) != NULL) {
          if (fndnxt(&flo->fb)) {
               return(maintainFile());
          }
          if (flo->misclib[0] != '\0') {
               return(0);
          }
     }
     while (1) {
          libptr=(flo->misclib[0] != '\0' ? libfind(flo->misclib)
                                          : nexthigh(flo->key1.libname));
          if (libptr != NULL) {
               stzcpy(flo->key1.libname,libptr->libname,FLNAMESZ);
               if (!(libptr->flags&FLGDOS)
                && (!(libptr->flags&FLGCBD) || libptr->path[0] != '\0')
                && fnd1st(&flo->fb,spr("%s"SLS STAR,libpath(libptr)),0)) {
                    return(maintainFile());
               }
               if (flo->misclib[0] != '\0') {
                    return(0);
               }
          }
          else {
               return(0);
          }
     }
}

INT
ulfileq(                           /* user uploaded file query             */
INT flag)
{
     struct ffblk fb;
     INT retval=0;

     if (fndfile(&fb,spr("%s"SLS STAR,userdir(1)),0)) {
          switch (flag) {
          case 2:   /* save file for resume */
               unlink(spr("%s"SLS".."SLS"%s",userdir(1),fb.ff_name));
               rename(spr("%s"SLS"%s",userdir(1),fb.ff_name),
                      spr("%s"SLS".."SLS"%s",userdir(1),fb.ff_name));
          case 1:   /* delete file */
               unlink(spr("%s"SLS"%s",userdir(1),fb.ff_name));
          }
          retval++;
          setmisc(fb.ff_name);
     }
     else {
          setmisc("");
     }
     return(retval);
}

LONG
dnlsec(                            /* time it takes to dl file of size siz */
LONG siz)
{
     LONG cps;

     return(siz/((cps=usrptr->baud/10L*(LONG)comeff/100L) > 0L ? cps : 100L));
}

LONG
dnlsecl(                           /* dnlsec() or 0 if Library free time   */
LONG siz,
struct fllib *libptr)
{
     return((libptr->flags&FLGFDL) ? 0L : dnlsec(siz));
}

struct fllib *
nexthigh(                          /* get next Library in order            */
const CHAR *oldlib)
{
     struct fllib *current,*best=NULL;
     INT loop;

     for (loop=0 ; loop < numoflib ; loop++) {
          if ((current=liboff(loop)) != NULL && strlen(current->libname)
           && stricmp(current->libname,oldlib) > 0) {
               if ((best == NULL)
             || (strcmp(best->libname,current->libname) > 0)) {
                    best=current;
               }
          }
     }
     return(best);
}

struct fllib *
nextlow(                           /* get previous Library in order        */
const CHAR *oldlib)
{
     struct fllib *current,*best=NULL;
     INT loop;

     for (loop=numoflib-1 ; loop >= 0 ; loop--) {
          if ((current=liboff(loop)) != NULL && strlen(current->libname)
           && stricmp(current->libname,oldlib) < 0) {
               if ((best == NULL)
             || (strcmp(best->libname,current->libname) < 0)) {
                    best=current;
               }
          }
     }
     return(best);
}

VOID
bubkwds(VOID)                      /* edit and sort keywords               */
{
     CHAR *current,*newarg;
     INT loop,loop2;

     for (loop=0 ; loop < dargc ; loop++) {
          cutpunc(dargv[loop]);              /* cut symbols                */
          loop2=strlen(dargv[loop]);
          if (loop2 > FLKEYSIZ-1) {          /* shorten long words         */
               dargv[loop][FLKEYSIZ-1]='\0';
          }
          else if (loop2 < 3) {              /* cut really short words     */
               dargc--;
               if (loop != dargc) {
                    dargv[loop--]=dargv[dargc];
               }
          }
     }
     for (loop=0 ; loop < (dargc-1) ; loop++) { /* sort them now           */
          current=dargv[loop];
          for (loop2=(loop+1) ; loop2 < dargc ; loop2++) {
               newarg=dargv[loop2];
               if (stricmp(current,newarg) > 0) {
                    dargv[loop2]=current;
                    current=dargv[loop]=newarg;
               }
          }
     }
     for (loop=0 ; loop < dargc-1 ; loop++) { /* eliminate duplicates      */
          if (stricmp(dargv[loop],dargv[loop+1]) == 0) {
               for (loop2=loop+1 ; loop2 < dargc-1 ; loop2++) {
                    dargv[loop2]=dargv[loop2+1];
               }
               dargc--;
               loop--;
          }
     }
}

VOID
sortlibs(VOID)                     /* sort Libraries (check for numbers)   */
{
     struct fllib *current,*newfll;
     INT loop,loop2;
     LONG curnum,newnum;
     static struct fllib swapmem;
     static INT curalphs=0;

     for (loop=0 ; loop < numoflib ; loop++) { /* eliminate null libs      */
          if (liboff(loop)->libname[0] == '\0') {
               for (loop2=(loop+1) ; loop2 < numoflib ; loop2++) {
                    newfll=liboff(loop2);
                    movmem(newfll,liboff(loop2-1),sizeof(struct fllib));
                    setmem(newfll,sizeof(struct fllib),0);
               }
               numoflib--;
          }
     }
     for (loop=0 ; loop < (numoflib-1) ; loop++) { /* sort them now by name*/
          current=liboff(loop);
          for (loop2=(loop+1) ; loop2 < numoflib ; loop2++) {
               newfll=liboff(loop2);
               if (stricmp(current->libname,newfll->libname) > 0) {
                    movmem(current,&swapmem,sizeof(struct fllib));
                    movmem(newfll,current,sizeof(struct fllib));
                    movmem(&swapmem,newfll,sizeof(struct fllib));
               }
          }
     }
     for (loop=0 ; loop < (numoflib-1) ; loop++) { /* sort sub-numerically */
          current=liboff(loop);
          for (loop2=(loop+1) ; loop2 < numoflib ; loop2++) {
               newfll=liboff(loop2);
               if ((curnum=atol(current->libname)) != 0L
                  && (newnum=atol(newfll->libname)) != 0L
                  && curnum > newnum) {
                    movmem(current,&swapmem,sizeof(struct fllib));
                    movmem(newfll,current,sizeof(struct fllib));
                    movmem(&swapmem,newfll,sizeof(struct fllib));
               }
          }
     }
     if (curalphs < numoflib) {
          if (alphlibs != NULL) {
               free(alphlibs);
          }
          curalphs=(numoflib/ALPHALC+1)*ALPHALC;
          alphlibs=(struct fllib **)alczer(curalphs*sizeof(struct fllib *));
     }
     for (loop=0 ; loop < numoflib ; loop++) {
          alphlibs[loop]=liboff(loop);
     }
     for (loop=0 ; loop < (numoflib-1) ; loop++) { /* sort them now by name*/
          for (loop2=(loop+1) ; loop2 < numoflib ; loop2++) {
               if (stricmp(alphlibs[loop]->libname,
                           alphlibs[loop2]->libname) > 0) {
                    newfll=alphlibs[loop];
                    alphlibs[loop]=alphlibs[loop2];
                    alphlibs[loop2]=newfll;
               }
          }
     }
     chkjoin();
}

VOID
darsdesc(                          /* parsin() on descedit                 */
INT limit,
CHAR chr)
{
     CHAR *sptr;
     INT loop;

     sptr=descedit;
     dargc=0;
     for (loop=0 ; loop < limit ; loop++) {
          dargv[loop]=sptr;
          if (sptr[0] != '\0') {
               sptr=strchr(sptr,chr);
               if (sptr == NULL) {
                    sptr=&descedit[strlen(descedit)];
               }
               else {
                    *sptr='\0';
                    sptr++;
               }
               dargc++;
          }
     }
}

CHAR *
lrange(                            /* return range of Library list         */
CHAR *libname)
{
     static CHAR retval[17];

     setmem(retval,17,0);
     if (libname[0] != '\0' && (strlen(libname) < 9)) {
          sprintf(retval,"%s Library",libname);
     }
     else {
          strcpy(retval,"All Libraries");
     }
     return(retval);
}

VOID
dispfhdr(                          /* display file header                  */
INT resetcur)  /* -1=cls but no curs, 0=home no curs, 1=cls, 2=partial cls */
{
     CHAR *sptr;

     setmbk(flmsg);
     if (abs(resetcur) == 1) {
          if (resetcur == 1) {
               btuclo(usrnum);
          }
          prfmsg(CLRSCN);
     }
     else if (resetcur == 2) {
          if (flo->flags&USRANSI) {
               prfmsg(CLRSUB);
               prfmsg(CLRLIST);
               prf("[4f");
          }
          else {
               resetcur=1;
          }
     }
     else {
          btuclo(usrnum);
          prf(" [f");
     }
     if (!(flo->flags&USRANSI)) {
          prf("\r");
     }
     usrptr->substt=(flo->flags&USRANSI) ? FILELST0 : FILELST2;
     if (resetcur > 0) {
          flo->cursor=(flo->flags&REVSRCH) ? NLISTER-1 : 0;
     }
     flo->prop=0;
     if (resetcur != 2) {
          prfmsg(FILELIST);
     }
     else {
          return;
     }
     switch (flo->keymeth) {
     case 0:
          setmisc(lrange(flo->lrange));
          prfmsg(FILELST0);
          strsrep(sptr=getmsg((flo->flags&USRANSI) ? FILEHFL0 : FILELSX0),
            "\r","[20f\r");
          prf(sptr);
          prf("[22f");
          break;
     case 1:
     case 6:
          setmisc(lrange(flo->lrange));
          prfmsg(FILELST1);
          strsrep(sptr=getmsg((flo->flags&USRANSI) ? FILEHFL1 : FILELSX1),
            "\r","[20f\r");
          prf(sptr);
          prf("[22f");
          break;
     case 2:
          setmisc(lrange(flo->lrange));
          prfmsg(FILELST2);
          strsrep(sptr=getmsg((flo->flags&USRANSI) ? FILEHFL2 : FILELSX2),
            "\r","[20f\r");
          prf(sptr);
          prf("[22f");
          break;
     case 3:
          setmisc(lrange(flo->lrange));
          prfmsg(FILELST3);
          strsrep(sptr=getmsg((flo->flags&USRANSI) ? FILEHFL3 : FILELSX3),
            "\r","[20f\r");
          prf(sptr);
          prf("[22f");
          break;
     case 4:
     case 7:
          setmisc(lrange(flo->lrange));
          prfmsg(FILELST4);
          strsrep(sptr=getmsg((flo->flags&USRANSI) ? FILEHFL4 : FILELSX4),
            "\r","[20f\r");
          prf(sptr);
          prf("[22f");
          break;
     case 5:
          setmisc(lrange(flo->lrange));
          prfmsg(FILELST5);
          strsrep(sptr=getmsg((flo->flags&USRANSI) ? FILEHFL5 : FILELSX5),
            "\r","[20f\r");
          prf(sptr);
          prf("[22f");
          break;
     case 8:
          setmisc(lrange(flo->lrange));
          prfmsg(FILELST6);
          strsrep(sptr=getmsg((flo->flags&USRANSI) ? FILEHFL6 : FILELSX6),
            "\r","[20f\r");
          prf(sptr);
          prf("[22f");
          break;
     case 9:
          setmisc(spr("%s (OS-Only)",flo->lrange));
          prfmsg(FILELST7);
          strsrep(sptr=getmsg((flo->flags&USRANSI) ? FILEHFL7 : FILELSX7),
            "\r","[20f\r");
          prf(sptr);
          prf("[22f");
     }
     setmisc("");
     if (flo->flags&USRANSI) {
          prfmsg(LISTFT);
     }
}

VOID
dlcharge(                          /* charge for d/l, pay royalty          */
LONG charge,
struct fllib *l)
{
     if (charge != 0L) {
          charge=hdedcrd(usaptr,charge,0,1);
          if (charge > 0L && l != NULL && l->royal > 0) {
               dfaSetBlk(flfdat);
               if (dfaAcqEQ(NULL,spc->libname,COMPLF)
             && !sameas(flf->ulby,"Sysop")) {
                    crdusr(flf->ulby,l2as(charge*(LONG)l->royal/100L),0,0);
               }
               dfaRstBlk();
          }
     }
}

VOID
dnlcount(                          /* modify # of times a file was d/l'ed  */
CHAR *libname,
CHAR *filname,
LONG ct)     /* if negative, adds abs(ct) to it.  if positive, sets it   */
{
     LONG times;

     dfaSetBlk(flfdat);
     if (dfaAcqEQ(NULL,compkey(libname,filname),COMPLF)) {
          times=(ct < 0 ? atol(flf->numdls)-ct : ct);
          if (times > 9999999L) {
               times=9999999L;
          }
          sprintf(flf->numdls,NUMSZP,times);
          dfaUpdateV(NULL,FLFILREC+strlen(flf->desc)+1);
     }
     dfaRstBlk();
}

INT                                /*   code describing result             */
maintainFile(VOID)                 /* handle file found by maint search    */
{
     struct fllib *libptr;

     if (okfname(flo->fb.ff_name)) {
          libptr=libfind(flo->key1.libname);
          makePath(flo->destpath,libpath(libptr),flo->fb.ff_name,GCMAXPTH);
          dfaSetBlk(flfdat);
          if (!dfaAcqEQ(NULL,compkey(flo->key1.libname,flo->fb.ff_name),COMPLF)) {
               if (flo->miscflag < 0
                && samend(flo->destpath,".ZIP") && openzip()) {
                    if (usrptr->flags&ISGCSU) {
                         prfmsg(DIZZYING);
                         sendres(unpad(stp4cs(prfbuf)));
                         return(2);
                    }
                    flo->retstt=SEARCHEM;
                    prfmsg(usrptr->substt=DIZZYING);
                    outprf(usrnum);
                    prf("");
               }
               else {
                    dofiler("");
               }
          }
          dfaRstBlk();
     }
     else {
          prfmsg(INVSKIP,flo->fb.ff_name,flo->key1.libname);
          if (usrptr->flags&ISGCSU) {
               sendres(unpad(stp4cs(prfbuf)));
          }
          else {
               outprf(usrnum);
          }
          prf("");
     }
     return(1);
}

VOID
dofiler(                           /* sysop search cycle warning           */
CHAR *desc)
{
     struct fllib *libptr;
     INT loop;

     dfaSetBlk(flfdat);
     if (!dfaAcqEQ(NULL,compkey(flo->key1.libname,flo->fb.ff_name),COMPLF)) {
          if (flo->miscflag < 0) {
               setmem(flf,FLFILREC+DESCSIZ,0);
               stzcpy(flf->libname,flo->key1.libname,FLNAMESZ);
               stzcpy(flf->filname,flo->fb.ff_name,FLFILENM);
               stzcpy(flf->udate,NOTAPPED,DATESZ);
               flf->utime=now();
               flf->siz=flo->fb.ff_fsize;
               stzcpy(flf->fdate,ddat2srt(flo->fb.ff_fdate),DATESZ);
               flf->tim=flo->fb.ff_ftime;
               stzcpy(flf->numdls,spr(NUMSZP,0L),NUMSZ);
               stzcpy(flf->ulby,usaptr->userid,UIDSIZ);
               if (flo->flags&APPTHEM) {
                    stzcpy(flf->udate,ddat2srt(today()),DATESZ);
                    flf->utime=now();
               }
               stzcpy(flf->desc,desc,DESCSIZ);
               dfaInsertV(NULL,FLFILREC+strlen(flf->desc)+1);
               if ((libptr=libfind(flf->libname)) != NULL) {
                    libptr->numfiles++;
                    if (flo->flags&APPTHEM) {
                         chuldate(libptr,flf->udate,1);
                    }
                    else {
                         libptr->appwait++;
                    }
                    libptr->totbytes+=flclfit(flf->siz,libptr->cluster);
                    libptr->flags|=LIBONG;
               }
               if (!longsrch) {
                    if (makwdlst(flf->desc,flf->filname)) {
                         for (loop=0 ; loop < dargc ; loop++) {
                              addkw(dargv[loop],flf->filname,flf->libname);
                         }
                    }
               }
          }
          prfmsg(NORECPRA,flo->fb.ff_name,flo->key1.libname,
                 (flo->miscflag < 0) ? "; added" : "");
          if (usrptr->flags&ISGCSU) {
               sendres(unpad(stp4cs(prfbuf)));
          }
          else {
               outprf(usrnum);
          }
          prf("");
     }
     dfaRstBlk();
}

VOID
gather(VOID)                       /* read sdi & diz files in              */
{
     INT lines=0;
     CHAR *path;
     FILE *fh;

     setmem(descedit,DESCSIZ,0);
     if (isfile(path=userdir(2))) {
          if ((fh=fopen(path,FOPRB)) != NULL) {
               lines=1;
               readin(1,fh,descedit);
               fclose(fh);
          }
          unlink(path);
     }
     if (isfile(path=userdir(3))) {
          if ((fh=fopen(path,FOPRB)) != NULL) {
               readin(NDESCLN-lines,fh,descedit);
               fclose(fh);
          }
          unlink(path);
     }
}

VOID
loadlibs(VOID)                     /* creates default lib, loads libs up.  */
{
     CHAR key[FLNAMESZ],*sptr;

     dfaSetBlk(flldat);
     if (!valname(deflname)) {
          deflname="MAIN";
     }
     if (!dfaAcqEQ(NULL,deflname,0)) {
          curlib=&libedt->lib;
          stzcpy(curlib->libname,deflname,FLNAMESZ);
          stzcpy(curlib->libdesc,defdesc,FLDESCSZ);
          stzcpy(curlib->primary,defplop,UIDSIZ);
          curlib->day=today();
          curlib->time=now();
          setmbk(flmsg);
          stzcpy(curlib->libop,getmsg(DEFLOP),KEYSIZ);
          stzcpy(curlib->autoap,getmsg(DEFAPP),KEYSIZ);
          stzcpy(curlib->keyreq,getmsg(FLVKEY),KEYSIZ);
          stzcpy(curlib->dlkey,getmsg(FLDKEY),KEYSIZ);
          stzcpy(curlib->ulkey,getmsg(DEFUL),KEYSIZ);
          stzcpy(curlib->overw,getmsg(DEFOVR),KEYSIZ);
          curlib->maxfil=10000L;
          curlib->maxbyt=10000000L;
          curlib->maxbup=200000L;
          curlib->cluster=clsize(libpath(curlib));
          setmem(libedt->ldesc,FLLDESCS*NLDLIN,0);
          dfaInsert(libedt);
          setmem(libedt,sizeof(struct libdisk),0);
          MKDIR(deflname);
          shocst(spr("LIBRARY CREATED: %s",deflname),
           "The \"%s\" Library was created",deflname);
     }
     numoflib=0;
     setmem(key,FLNAMESZ,0);
     while (dfaAcqGT(libupd,key,0)) {
          curlib=liboff(numoflib++);
          if (curlib == NULL) {
               catastro("LIBRARY MEMORY ERROR - REBUILD %s",
               fnmcse("GALFILL.DAT"));
          }
          movmem(&libupd->lib,curlib,sizeof(struct fllib));
          if (sameto("_LIBOP",curlib->libop)) {
               curlib->libop[0]='\0';
          }
          if (curlib->path[0] != '\0'
           && !sameas(sptr=fixpath(curlib->path),curlib->path)) {
               stzcpy(curlib->path,sptr,PATHSIZE);
               curlib->flags|=LIBCHN;
          }
          if (!(curlib->flags&FLGCBD)) {
               MKDIR(libpath(curlib));
          }
          stzcpy(key,curlib->libname,FLNAMESZ);
     }
     setmem(libupd,sizeof(struct libdisk),0);
     sortlibs();
     scanlibs();
}

VOID
mopitup(VOID)                      /* clear spec, files, etc.              */
{
     INT loop,savusn;
     struct taglib *tag;
     GBOOL found=FALSE;
     CHAR *l,*f;

     switch (-ftag->status) {
     case TGCOPY:
          if (cdst != NULL) {
               fclose(cdst);
               cdst=NULL;
          }
          if (csrc != NULL) {
               fclose(csrc);
               csrc=NULL;
          }
          break;
     case TGOTHER:
          if (onsysn(uacoff(ftag->usrnum)->userid,1)
              && !(othusp->flags&NOINJO)) {
               setmbk(flmsg);
               prfmlt(BEEP);
               if (othusp->state == flstt && othusp->substt == PLSWAIT) {
                    othusp->substt=MMENU;
               }
               prfmlt(NOTYFILE,ftag->filname,ftag->reflib);
               rstmbk();
               injoth();
               clrmlt();
          }
          break;
     case TGLOCAL:
          if (sameas(ftag->filname,"*")) {
               for (loop=0 ; loop < systags ; loop++) {
                    if (ftag == tagoff(loop)) {
                         unlink(spr("%s"SLS"tags%d.fil",copydir,loop));
                         break;
                    }
               }
          }
          break;
     case TGDLTMP:
          l=ftag->libname;
          f=ftag->filname;
          for (loop=0 ; loop < systags ; loop++) {
               if (ftag != (tag=tagoff(loop)) && tag->status > TGEMPTY) {
                    if (sameas(f,tag->filname) && sameas(l,tag->libname)) {
                         found=TRUE;
                         break;
                    }
               }
          }
          if (!found) {
               for (loop=0 ; loop < nterms ; loop++) {
                    if (sameas(f,lcsarr[loop].filname)
                       && sameas(l,lcsarr[loop].libname)) {
                         found=TRUE;
                         break;
                    }
               }
               if (!found) {
                    unlink(spr("%s"SLS"%s"SLS"%s",copydir,l,f));
               }
          }
     }
     savusn=usrnum;
     if (ftag->usrnum >= 0 && ftag->usrnum < nterms
      && onsysn(uacoff(ftag->usrnum)->userid,1)) {
          curusr(othusn);
          setftu();
          for (loop=0 ; loop < ftuptr->numftg ; loop++) {
               ftgptr=&ftgusr[loop];
               if (ftag == spc) {
                    untag(loop);
                    removetg(loop--);
               }
          }
     }
     if (savusn >= 0 && savusn < nterms) {
          curusr(savusn);
     }
     setmem(ftag,sizeof(struct taglib),0);
}

VOID
moploop(VOID)                      /* mop up all tag entries               */
{
     INT loop;

     for (loop=systags-1 ; loop >= 0 ; loop--) {
          ftag=tagoff(loop);
          if (ftag->status < TGEMPTY) {
               mopitup();
          }
     }
}

INT
notify(                            /* notify to operators                  */
INT logon)                         /* called during logon                  */
{
     INT doit,loop,beeped=0;
     struct fllib *libptr;

     setmbk(flmsg);
     clrprf();
     prfmsg(NOTIFTOP);
     for (loop=0 ; loop < numoflib ; loop++) {
          doit=0;
          if ((libptr=liboff(loop))->appwait > 0
           && valname(libptr->libname)
           && haskey(libptr->keyreq)) {
               if (!logon || (haskey(flsysop) && notifsys)
             || (isflop(libptr) && notiflop)) {
                    doit=1;
                    curlib=libptr;
               }
          }
          if (doit) {
               if (!beeped++) {
                    prfmsg(BEEP);
               }
               if (!logon || (beeped < 10)) {
                    if (curlib->appwait == 1) {
                         prfmsg(NOTIFY);
                    }
                    else {
                         prfmsg(NOTIFYM);
                    }
               }
               else {
                    prfmsg(MORENOT);
                    break;
               }
          }
     }
     if (beeped) {
          outprf(usrnum);
     }
     clrprf();
     return(beeped);
}

VOID
readin(                           /* get contents of a txt file to buffer */
INT lines,
FILE *fptr,
CHAR *stg)
{
     INT loop,gotline=1;

     for (loop=0 ; (loop < lines) && gotline ; loop++) {
          gotline=readline(fptr);
          stzcpy(&stg[strlen(stg)],input,SDESCLN);
          strcat(stg,"\r");
     }
}

VOID
regtvars(VOID)                     /* register all text variables here     */
{
     register_textvar("FL_NAME",tvname);     /* Library name               */
     register_textvar("FL_DESC",tvdesc);     /* Library description        */
     register_textvar("FL_DESC0",tvdesc0);   /* Library long desc. line 1  */
     register_textvar("FL_DESC1",tvdesc1);   /* Library long desc. line 2  */
     register_textvar("FL_DESC2",tvdesc2);   /* Library long desc. line 3  */
     register_textvar("FL_DESC3",tvdesc3);   /* Library long desc. line 4  */
     register_textvar("FL_DESC4",tvdesc4);   /* Library long desc. line 5  */
     register_textvar("FL_FNUM",tvfnum);     /* # of files in Library      */
     register_textvar("FL_FAPP",tvfapp);     /* # of unapp files in lib.   */
     register_textvar("FL_CTIM",tvctim);     /* lib. creation date & time  */
     register_textvar("FL_CTIML",tvctiml);   /* long lib. crt date & time  */
     register_textvar("FL_TAGS",tvtags);     /* # of tagged files open     */
     register_textvar("FL_TSHMSG",tvtshmsg); /* tagged file string         */
     register_textvar("FL_MISC",tvmisc);     /* misc string                */
     register_textvar("FL_INIT",tvinit);     /* init tvars for use outside */
     register_textvar("FL_BYTU",tvbytu);     /* max u/l size               */
     register_textvar("FL_BYTT",tvbytt);     /* max Library size           */
     register_textvar("FL_BYTO",tvbyto);     /* bytes open for upload      */
     register_textvar("FL_FILT",tvfilt);     /* max Library files          */
     register_textvar("FLF_DMIN",tvdnlmin);  /* est. minutes to d/l        */
     register_textvar("FLF_FDATE",tvfdate);  /* DOS date MM/DD/YY or UNAPP */
     register_textvar("FLF_FDATES",tvfdates);/* short MM/YY or "UNAPP"     */
     register_textvar("FLF_FDATEL",tvfdatel);/* long file date MM/DD/YYYY  */
     register_textvar("FLF_NAME",tvfname);   /* filename                   */
     register_textvar("FLF_LIB",tvflib);     /* Library name               */
     register_textvar("FLF_SIZEK",tvfsizek); /* file size in K             */
     register_textvar("FLF_SIZE",tvfsize);   /* file size in bytes         */
     register_textvar("FLF_TAGK",tvtagk);    /* file tag A-? or just A     */
     register_textvar("FLF_TIMES",tvftimes); /* # of times downloaded      */
     register_textvar("FLF_UDATE",tvudate);  /* appdate or "UNAPPROVED"    */
     register_textvar("FLF_UDATEL",tvudatel);/* long approval date         */
     register_textvar("FLF_ULBY",tvfulby);   /* file uploaded by           */
     register_textvar("COMEFF",tvcomeff);    /* communications efficiency  */
}

VOID
removetg(                          /* untag a file                         */
INT n)
{
     setftu();
     if ((n >= 0) && (n < ftuptr->numftg)) {
          if ((n+1) < ftuptr->numftg) {
               movmem(ftgusr+n+1,ftgusr+n,
                      (ftuptr->numftg-(n+1))*sizeof(struct ftg));
          }
          ftuptr->numftg--;
     }
}

VOID
strcrep(                           /* replace a char in a string w/ a char */
CHAR *stg,
CHAR from,
CHAR to)
{
     while (*stg != '\0') {
          if (*stg == from) {
               *stg=to;
          }
          stg++;
     }
}

VOID
unbreak(VOID)                      /* remove n,q,c message                 */
{
     INT savbrk;

     savbrk=usaptr->scnbrk;
     usaptr->scnbrk=CTNUOS;
     rstrxf();
     usaptr->scnbrk=savbrk;
}

VOID
iflstyp(                           /* ask for type of list user wants      */
CHAR c) {

     INT flag=0;

     switch (c) {
     case 'X':
          retmenu(0);
          break;
     case 'D':
     case '\0':
     case '.':
          flag=2;
          break;
     case 'Q':
          flag=7;
          break;
     case 'F':
          flag=3;
          break;
     case 'W':
          flag=6;
          break;
     case 'K':
          flag=4;
          break;
     case 'N':
          flag=5;
     }
     if (flag) {
          dsearch(0,flag);
     }
}

VOID
iflslib(                           /* current or all Libraries?            */
CHAR c) {

     INT flag=0;

     switch (c) {
     case 'X':
          retmenu(0);
          break;
     case 'C':
     case '\0':
     case '.':
          flag=2;
          break;
     case 'A':
          flag=3;
     }
     if (flag) {
          dsearch(1,flag);
     }
}

VOID
iaskword(                          /* what keywords to search on?          */
CHAR *stg) {

     if (stg[0] == '\0' || sameas(stg,"x")) {
          retmenu(0);
     }
     else if (sameas(stg,"?")) {
          prfmsg(usrptr->substt=ASKWHLPA);
     }
     else if (fparsrch(stg)) {
          btumil(usrnum,DFTIMX);
          dsearch(1,((flo->flags&ABOUPRF) ? 1 : flu->mylib));
     }
}

VOID
iaskname(                          /* where to begin search in filenames   */
CHAR *stg) {

     if (sameas(stg,"x")) {
          retmenu(0);
     }
     if (sameas(stg,".")) {
          *stg='\0';
     }
     stzcpy(flo->miscfil,stg,FLFILENM);
     dsearch(1,((flo->flags&ABOUPRF) ? 1 : flu->mylib));
}

INT
ifdesced(                          /* edit file, enter filename            */
CHAR *stg)
{
     stzcpy(flo->key1.libname,curlib->libname,FLNAMESZ);
     stzcpy(flo->key1.filname,stg,FLFILENM);
     dfaSetBlk(flfdat);
     if (sameas(stg,"x")) {
          retmenu(1);
     }
     else if (dfaAcqEQ(NULL,&flo->key1,COMPLF)) {
          flo->retstt=OPMENU;
          usrptr->substt=PRESENTR;
          bgnfiled(0);
          outprf(usrnum);
          return(1);
     }
     else {
          locsysfl(stg);
     }
     return(0);
}

VOID
iprefers(                          /* preference menu                      */
CHAR c)
{
     switch (c) {
     case '\0':
     case 'X':
          retmenu(0);
          break;
     case 'P':
          usrptr->substt=TRANSPRT;
          break;
     case 'T':
          usrptr->substt=ASKTYPA;
          break;
     case 'R':
          usrptr->substt=ASKLIB;
          break;
     case 'C':
          flu->askme=flu->mylib=flu->mytyp=0;
          flu->proto[0]='\0';
          updusr(flu);
          prfmsg(OKPCLEAR);
     }
}

VOID
imanmnu(                           /* Library management menu              */
CHAR c)
{
     switch (c) {
     case '\0':
     case 'X':
          retmenu(1);
          break;
     case '1':
          flo->miscflag=1;
          usrptr->substt=WARNMARK;
          break;
     case '2':
          flo->miscflag=2;
          usrptr->substt=WARNMARK;
          break;
     case '3':
          flo->miscflag=3;
          usrptr->substt=WARNMARK;
          break;
     case '4':
          flo->miscflag=4;
          usrptr->substt=WARNMARK;
     }
}

VOID
ibigcopy(                          /* begin massive file copy              */
CHAR *stg)
{
     size_t l;

     if (stg[0] != '\0') {
          if (sameas(stg,"x")) {
               retmenu(1);
               return;
          }
          else if (sameas(stg,"*")) {
               setmem(&flo->key1,sizeof(struct key1),0);
               flo->miscflag=-2;
               flo->flags|=APPTHEM;
               stzcpy(flo->misclib,curlib->libname,FLNAMESZ);
               prfmsg(usrptr->substt=SEARCHEM);
               unbreak();
               btuinj(usrnum,CYCLE);
               return;
          }
          else if (fnd1st(&flo->fb,stg,0)) {
               while ((flo->fb.ff_attrib&FAMDIR) && fndnxt(&flo->fb)) {
               }
               if (!(flo->fb.ff_attrib&FAMDIR)) {
                    flo->flags|=AXSUSER;
                    MKDIR(userdir(1));
                    unbreak();
                    while ((l=strlen(stg)) != 0
                        && stg[l-1] != SL && stg[l-1] != ':') {
                         stg[l-1]='\0';
                    }
                    stzcpy(flo->keylist,stg,FLKEYLST);
                    unbreak();
                    btuinj(usrnum,CYCLE);
                    prfmsg(usrptr->substt=BIGCPY);
                    flo->fsrc=flo->fdst=NULL;
                    return;
               }
          }
          prfmsg(NOFILPTH);
     }
}

VOID
iwarnmrk(                          /* just warn sysop / actually do stuff  */
CHAR *stg)
{

     if (stg[0] != '\0') {
          if (sameas(stg,"x")) {
               usrptr->substt=MANAGMNU;
          }
          else {
               setmem(&flo->key1,sizeof(struct key1),0);
               setmem(flo->misclib,FLNAMESZ,0);
               if (flo->miscflag < 3) {
                    stzcpy(flo->misclib,curlib->libname,FLNAMESZ);
                    if (flo->miscflag == 1) {
                         stzcpy(flo->key1.libname,flo->misclib,FLNAMESZ);
                    }
               }
               if (lingyn(*stg) == 'Y') {
                    flo->miscflag=-flo->miscflag;
               }
               prfmsg(usrptr->substt=SEARCHEM);
               btuinj(usrnum,CYCLE);
          }
     }
}

VOID
idelfil(                           /* delete files from Library            */
CHAR *stg)
{
     if (stg[0] != '\0') {
          if (sameas(stg,"x") || (nlibtagd() == 0)) {
               setmbk(flmsg);
               retmenu(1);
          }
          else {
               if (lingyn(*stg) == 'Y') {
                    flo->flags|=DELTHEM;
               }
               else {
                    flo->flags&=~DELTHEM;
               }
               usrptr->substt=FILDELA;
               btuinj(usrnum,CYCLE);
          }
     }
}

INT
isellib(                           /* select a Library                     */
CHAR *stg)
{
     INT retval=1;
     struct fllib *libptr;

     if (stg[0] != '\0') {
          if (sameas(stg,"?")) {
               flo->index=0;
               flo->retstt=usrptr->substt;
               usrptr->substt=LIBLST;
               prfmsg(LIBLST);
               btuinj(usrnum,CYCLE);
          }
          else if (sameas(stg,"x") || sameas(stg,".")) {
               if (sameas(stg,".") && usrptr->substt == SELLIB) {
                    flo->flags|=LONGDSC;
               }
               retmenu(usrptr->substt == SELLIB ? 0 : 1);
          }
          else {
               if ((libptr=libfind(stg)) == NULL || !visilib(libptr)) {
                    prfmsg(INVALIB);
               }
               else if (usrptr->substt == SELLIB3 && (libptr->flags&FLGDOS)) {
                    prfmsg(NODOSJN);
               }
               else if (usrptr->substt == SELLIB2 && !isflop(libptr)) {
                    prfmsg(NOSELOP);
               }
               else {
                    stzcpy(flu->lib,libptr->libname,FLNAMESZ);
                    curlib=setuaxs();
                    if (usrptr->substt == SELLIB) {
                         usrptr->substt=MMENU;
                         flo->flags|=LONGDSC;
                         while (morcnc() == ' ') {
                              cncchr();
                         }
                         if (!morcnc()) {
                              condex();
                         }
                    }
                    else if (usrptr->substt == SELLIB2) {
                         retmenu(1);
                    }
                    else {
                         usrptr->substt=CHAINMNU;
                    }
                    if (curlib == NULL) {
                         retval=0;
                         clrprf();
                    }
               }
          }
     }
     return(retval);
}

INT
othrsin(                           /* are others in this lib?              */
CHAR *libname)
{
     INT retval=0,saveu;

     saveu=usrnum;
     for (othusn=0 ; othusn < nterms ; othusn++) {
          if (saveu != othusn) {
               if ((othusp=usroff(othusn))->usrcls == ACTUSR) {
                    fluoff(othusn);
                    if ((othusp->state == flstt)
                       && sameas(libname,flu->lib)) {
                         othuap=uacoff(othusn);
                         retval=1;
                         break;
                    }
               }
          }
     }
     fluoff(saveu);
     return(retval);
}

INT
idellibn(                          /* delete a Library                     */
CHAR *stg)
{
     struct fllib *libptr;

     if (stg[0] == '\0' || sameas(stg,"x")) {
          retmenu(1);
     }
     else if (sameas(stg,"?")) {
          prfmsg(HELPDLIB);
     }
     else if (sameas(stg,deflname)) {
          prfmsg(CANTDEFL);
     }
     else if (valname(stg)) {
          if ((libptr=libfind(stg)) == NULL) {
               prfmsg(LIBNOEXT);
          }
          else if (othrsin(libptr->libname)) {
               prfmsg(LIBNODEL,othuap->userid);
          }
          else if ((othusn=w2writ(libptr->libname,"*",1)) != NOCONFLICT) {
               prfmsg(LIBNODEL,uacoff(othusn)->userid);
          }
          else {
               stzcpy(flo->misclib,libptr->libname,FLNAMESZ);
               untagall(libptr->libname,"");
               setmem(libptr,sizeof(struct fllib),0);
               sortlibs();
               scanlibs();
               curlib=setuaxs();
               flo->miscflag=0;
               prfmsg(usrptr->substt=DELLIB);
               outprf(usrnum);
               btuinj(usrnum,CYCLE);
               donewrit(1);
               return(1);
          }
     }
     return(0);
}

INT
itagman(                           /* manage tagged files                  */
CHAR *stg)
{
     INT flag,loop;

     flo->retstt=TAGMAN;
     if (stg[0] == '\0' || sameas(stg,"?")) {
          if (ftuptr->numftg > 0) {
               prfmsg(TAGMAN);
          }
          return(0);
     }
     else if (sameas(stg,"X")) {
          if (flo->flags&OFTGMAN) {
               usrptr->substt=PRESENTR;
               flo->retstt=FILELST0;
               inpfunc();
               return(1);
          }
          else {
               retmenu(0);
               return(0);
          }
     }
     if (toupper(*stg) == 'D' || sameas(stg,"ALL")) {
          flo->retstt=usrptr->substt;
          flo->pflg=0;
          if (flu->askme) {
               usrptr->substt=LOGOFF;
               return(0);
          }
          if (!sameas(stg,"ALL") && strlen(stg) > 1) {
               stg++;
          }
          else if (morcnc()) {
               stg=cncall();
          }
          else {
               stg=protocol();
          }
          if (*stg == '?' || *stg == '\0') {
               prfmsg(PROTHDR);
          }
          ftgdnl(sameas(stg,"?") ? "" : stg,retoin);
          outprf(usrnum);
          return(0);
     }
     flag=0;
     if (*stg == '-') {
          stg++;
          flag=1;
     }
     if (sameas(stg,"ALL")) {
          flo->retstt=usrptr->substt;
          clrprf();
          prfmsg(ALLUNTAG);
          ftgdnl("-ALL",retoinx);
          setmbk(flmsg);
          prf("");
          outprf(usrnum);
          prf("");
          if (flo->flags&OFTGMAN) {
               usrptr->substt=PRESENTR;
               flo->retstt=FILELST0;
               inpfunc();
               return(1);
          }
          retmenu(0);
          injacr();
          return(1);
     }
     loop=atoi(stg);
     if (strlen(stg) < 4 && loop && (loop <= ftuptr->numftg)) {
          if (!flag) {
               if (!ftgnew()) {
                    prfmsg(UNTAG1A);
               }
               else {
                    flo->retstt=usrptr->substt;
                    flo->pflg=loop;
                    if (flu->askme) {
                         usrptr->substt=LOGOFF;
                         return(0);
                    }
                    dnlstart(0);
                    outprf(usrnum);
                    return(1);
               }
          }
          else {
               stg--;
               ftgdnl(stg,retoin);
               setmbk(flmsg);
               clrprf();
               if (ftuptr->numftg > 0 || (flo->flags&OFTGMAN)) {
                    retoin();
                    prf("");
               }
               return(1);
          }
     }
     return(0);
}

INT
ientdl(                            /* enter fn to download                 */
CHAR *stg)
{
     struct fllib *libptr;
     INT flag,curall;
     CHAR *prtcl,*filname;

     curall=defallib;
     setmem(flo->miscfil,FLFILENM,0);
     if (stg[0] == '\0' || sameas(stg,"?")) {
          prfmsg(defallib ? ENTDLHL1 : ENTDLHL2);
          return(0);
     }
     else if (sameas(stg,"x") || strstr(stg,"..") != NULL) {
          retmenu(0);
          return(0);
     }
     while (morcnc() == ' ') {
          cncchr();
     }
     strcpy(flo->savprot,strlen(prtcl=cncall()) < 3 ? prtcl : "");
     if ((filname=strchr(stg,'/')) != NULL
      || (filname=strchr(stg,'\\')) != NULL) {
          *filname++='\0';
          if ((libptr=libfind(stg)) != NULL && visilib(libptr)) {
               stzcpy(flu->lib,libptr->libname,FLNAMESZ);
               curlib=setuaxs();
               if (curlib == NULL) {
                    condex();
                    return(1);
               }
               curall=1;
          }
          stg=filname;
          if (stg[0] == '\0') {
               prfmsg(defallib ? ENTDLHL1 : ENTDLHL2);
               return(0);
          }
     }
     flag=fspex(stg,curall ? "" : curlib->libname,0);
     if (flag != 1) {
          wipetag();
          setmem(flo->miscfil,FLFILENM,0);
          if ((strchr(stg,'*') != NULL) || (strchr(stg,'?') != NULL)) {
               if ((curlib->flags&FLGDOS)
                && fndfile(&flo->fb,spr("%s"SLS"files",curlib->libname),0)) {
                    prfmsg(NOWLDTAG);
                    return(0);
               }
               stzcpy(flo->miscfil,fnmcse(stg),FLFILENM);
               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;
                    flo->wtsiz=0L;
                    if (initsrc()) {
                         flo->retstt=WLDSRCH;
                         prfmsg(usrptr->substt=CYCIDX);
                         btuinj(usrnum,CYCLE);
                    }
                    else {
                         setmisc(flo->miscfil);
                         prfmsg(usrptr->substt=WLDSRCH);
                         setmisc("");
                         btuinj(usrnum,CYCLE);
                    }
                    if (!(curlib->flags&FLGDOS)) {
                         wldstuff(flo->u.key4.filname);
                    }
                    return(0);
               }
               flo->styp=7;
               srcinit(6,curall ? "" : curlib->libname);
               return(0);
          }
          if (curlib->flags&FLGDOS) {
               prfmsg(NOSFL,stg);
               return(0);
          }
          dfaSetBlk(flfdat);
          setmem(flo->miscfil,FLFILENM,0);
          stzcpy(flo->u.key4.filname,stg,FLFILENM);
          if (curall) {
               stzcpy(flo->u.key4.libkey,"",FLNAMESZ);
               if ((dfaAcqGT(NULL,&flo->u.key4,COMPFL)
                 && sameas(flf->filname,stg))
                || dfaAcqLT(NULL,&flo->u.key4,COMPFL)) {
                    stzcpy(flo->miscfil,flf->filname,FLFILENM);
               }
          }
          else {
               stzcpy(flo->u.key1.libname,curlib->libname,FLNAMESZ);
               stzcpy(flo->u.key1.filname,stg,FLFILENM);
               if (dfaAcqLT(NULL,&flo->u.key1,COMPLF)) {
                    stzcpy(flo->miscfil,flf->filname,FLFILENM);
               }
          }
          flo->styp=curall && (flag > 1) ? 8 : 3;
          stzcpy(flo->lrange,curall ? "" : curlib->libname,FLNAMESZ);
          srcinit(2,flo->lrange);
     }
     else {
          flag=fspex(stg,curall ? "" : curlib->libname,1);
          if (usrptr->state == flstt) {
               if (flag == -1 && !sameto("T",flo->savprot)) {
                    usrptr->substt=PLSWAIT;
               }
               else if (usrptr->substt != LOGOFF) {
                    prfmsg(ATAGGED,fnmcse(stg));
                    outprf(usrnum);
                    prf("");
                    retmenu(0);
               }
          }
     }
     return(0);
}

INT
fspex(                             /* count up # of exact matches          */
CHAR *stg,
CHAR *lib,
INT sub)
{
     static struct key4 key;
     INT retval=0,loop;
     struct fllib *libptr;
     CHAR fin[FLFILENM];
     LONG charge;

     setmem(&key,sizeof(struct key4),0);
     stzcpy(key.filname,stg,FLFILENM);
     stzcpy(fin,stg,FLFILENM);
     if (curlib->flags&FLGDOS) {
          if (!fnd1st(&flo->fb,spr("%s"SLS"%s",libpath(curlib),fin),0)) {
               if (sameas(lib,curlib->libname)) {
                    return(0);
               }
          }
          else {
               getShortName(fin
                           ,spr("%s"SLS"%s",libpath(curlib),flo->fb.ff_name)
                           ,FLFILENM);
               if (!fndnxt(&flo->fb)) {
                    if (sub) {
                         if (!sameto("T",flo->savprot)
                          && candlnow(curlib->libname,fin) > 0) {
                              flo->retstt=usrptr->substt;
                              if (!submit(curlib->libname,fin,
                                          flo->lrange,DOWNLOD,0)) {
                                   return(0);
                              }
                              if (usrptr->state != flstt) {
                                   rstrxf();
                                   return(1);
                              }
                         }
                         if (submit(curlib->libname,fin,
                                    flo->lrange,NOTVIEW,1)) {
                              return((curlib->flags&FLGCBD) ? -1 : 1);
                         }
                         return(0);
                    }
                    if (strchr(stg,'*') != NULL || strchr(stg,'?') != NULL) {
                         if (fndfile(&flo->fb,
                                     spr("%s"SLS"files",curlib->libname),0)) {
                              return(0);
                         }
                    }
                    return(1);
               }
               return(2);
          }
     }
     dfaSetBlk(flfdat);
     while (dfaAcqGT(NULL,&key,COMPFL) && sameas(fin,flf->filname)
         && (lib[0] != '\0' || retval < 2)) {
          stzcpy(key.libkey,flf->libname,FLNAMESZ);
          libptr=libfind(flf->libname);
          if (haslibkey(libptr,libptr->dlkey)
           && (!notapped(flf->udate) || isflop(libptr))) {
               if (lib[0] == '\0' || sameas(lib,libptr->libname)) {
                    if (sub) {
                         if (!sameto("T",flo->savprot)
                          && candlnow(flf->libname,flf->filname) > 0) {
                              prfmsg(DLDESC);
                              charge=dnlchg(flf->siz,flf->libname);
                              if (charge != 0L) {
                                   prfmsg(DLDESCC,l2as(charge));
                              }
                              stzcpy(descedit,flf->desc,DESCSIZ);
                              darsdesc(NDESCLN,'\r');
                              for (loop=0 ; loop < NDESCLN ; loop++) {
                                   if (dargv[loop][0] != '\0') {
                                        if (loop == 0) {
                                             prfmsg(DLDESCD);
                                        }
                                        prf("   %s\r",dargv[loop]);
                                   }
                              }
                              if (isripu()) {
                                   prf("\r%c",20);
                              }
                              flo->retstt=usrptr->substt;
                              if (!submit(flf->libname,flf->filname,
                                          flo->lrange,DOWNLOD,0)) {
                                   return(0);
                              }
                              if (usrptr->state != flstt) {
                                   rstrxf();
                                   return(1);
                              }
                         }
                         if (submit(flf->libname,flf->filname,
                                    flo->lrange,NOTVIEW,1)) {
                              return((libptr->flags&FLGCBD) ? -1 : 1);
                         }
                         return(0);
                    }
                    retval++;
               }
          }
     }
     dfaRstBlk();
     return(retval);
}

INT
ioverw(                            /* overwrite existing file?             */
CHAR c)
{
     flo->flags&=~REUPLOD;
     switch (c) {
     case '?':
          prfmsg(REUPHLP);
          break;
     case 'Y':
          flo->flags|=REUPLOD;
          flo->retstt=ENTULFIL;
          fileup(flo->miscfil,morcnc() ? cncall() : "?",fupfil);
          outprf(usrnum);
          clrprf();
          return(1);
     default:
          donewrit(0);
          usrptr->substt=ENTULFIL;
     case '\0':
          break;
     }
     return(0);
}

INT
ientul(                            /* enter fn to upload                   */
CHAR *stg)
{
     CHAR *wrd;

     setmem(flo->miscfil,FLFILENM,0);
     if (*stg == '\0' || sameas(stg,"x")) {
          retmenu(0);
     }
     else if (sameas(stg,"?")) {
          prfmsg(ULHELP);
     }
     else if (sameas("M",stg)) {
          if (curlib->flags&FLGDOS) {
               prfmsg(NOFILDOS);
          }
          else {
               usrptr->substt=ULMOD;
          }
     }
     else {
          if (okfname(stg)) {
               strcpy(flo->miscfil,stg);
               switch (usrupd(curlib,flo->miscfil)) {
               case 2:
                    prfmsg(RUPCFL,curlib->libname,flo->miscfil);
                    return(0);
               case 1:   /* file exists, may re-upload */
                    usrptr->substt=OVERW;
                    return(0);
               case 0:   /* file exists, may not re-upload */
                    donewrit(0);
                    prfmsg(CANTOVER);
                    return(0);
               case -1:  /* file does not exist */
                    break;
               }
          }
          if (sameas(stg,"*") || flo->miscfil[0] != '\0') {
               flo->flags&=~REUPLOD;
               flo->retstt=usrptr->substt;
               while (morcnc() == ' ') {
                    cncchr();
               }
               wrd=cncwrd();
               fileup(flo->miscfil,wrd[0] != '\0' ? wrd : "?",fupfil);
               outprf(usrnum);
               clrprf();
               return(1);
          }
     }
     return(0);
}

INT
iulmod(                            /* enter name of file to modify         */
CHAR *stg)
{
     stzcpy(flo->key1.libname,curlib->libname,FLNAMESZ);
     stzcpy(flo->key1.filname,stg,FLFILENM);
     dfaSetBlk(flfdat);
     if (*stg == '\0') {
          return(0);
     }
     if (sameas(stg,"x")) {
          retmenu(0);
     }
     else if (dfaAcqEQ(NULL,&flo->key1,COMPLF)) {
          if (ucanmod()) {
               flo->retstt=usrptr->substt;
               usrptr->substt=PRESENTR;
               bgnfiled(0);
               outprf(usrnum);
               return(1);
          }
     }
     else {
          prfmsg(NOSFL,flo->key1.filname);
     }
     return(0);
}

INT
ucanmod(VOID)                      /* user can modify current file         */
{
     if (isflop(curlib)) {
          return(1);
     }
     if (!sameas(flf->ulby,usaptr->userid)) {
          prfmsg(DIDNU);
          return(0);
     }
     if (!notapped(flf->udate)
      && !haslibkey(curlib,curlib->autoap)
      && !haslibkey(curlib,curlib->overw)) {
          prfmsg(MFAPP);
          return(0);
     }
     return(1);
}

INT
ucanovw(                           /* can current user overwrite a file?   */
struct fllib * pLib,               /*   library in which file resides      */
struct flfile * pFile)             /*   file to be overwritten             */
{
     return(haslibkey(pLib,pLib->overw)   /* (haslibkey also checks libop) */
         || (sameas(pFile->ulby,usaptr->userid)
          && (notapped(pFile->udate) || haslibkey(pLib,pLib->autoap))));
}

VOID
exitview(VOID)
{
     if (flo->atend == LSTNONE) {
          deresume();
     }
     btuclo(usrnum);
     btupbc(usrnum,0);
     prfmsg(CLRSCN);
     rstrxf();
     btutsw(usrnum,usaptr->scnwid);
     dotags(0);
     echonu(usrnum);
     btutrg(usrnum,0);
     if ((flo->flags&USRANSI) && !(flo->flags&UNOINJO)) {
          usrptr->flags&=~NOINJO;
     }
     setftu();
     notidl();
     outprf(usrnum);
     retmenu(0);
}

VOID
dcurs(                             /* display cursor                       */
INT und)
{
     if ((flo->flags&USRANSI) && flo->tdline[flo->cursor] != 0) {
          setmbk(flmsg);
          prfmsg(und ? UNCURSED : CURSED,abs(flo->tdline[flo->cursor])+3,
           flo->tags[flo->cursor].filname);
          rstmbk();
     }
}

INT
curspos(                           /* display (set) cursor                 */
INT set)                           /* set = -1 then just display           */
{
     INT hi;

     for (hi=NLISTER-1 ; hi >= 0 ; hi--) {
          if (flo->tdline[hi] != 0) {
               break;
          }
     }
     if (set > hi) {
          set=0;
     }
     else if (set < 0) {
          set=(hi >= 0 ? hi : 0);
     }
     if (flo->tdline[set] == 0) {
          for (hi=0 ; hi < NLISTER ; hi++) {
               if (flo->tdline[hi] != 0) {
                    set=hi;
                    break;
               }
          }
     }
     if (flo->cursor != set) {
          dcurs(1);
          flo->cursor=set;
          dcurs(0);
          return(1);
     }
     return(0);
}

VOID
clstags(VOID)                      /* clear the on-screen tags             */
{
     INT loop;

     for (loop=0 ; loop < NLISTER ; loop++) {
          if (flo->tdline[loop] < 0) {
               flo->tdline[loop]=-flo->tdline[loop];
          }
     }
}

INT
ientret(                           /* other file view handler              */
CHAR *stg)
{
     INT tagd,loop;

     if (stg[0] == '\0') {
          return(0);
     }
     if (sameas(stg,"&")) {
          if (!dlfrom(flo->tags[flo->hold].libname)) { /* dont let view */
               dlcant();
          }
          else if ((tagd=candlnow(flo->tags[flo->hold].libname,
                      flo->tags[flo->hold].filname)) > DOWNLOD) {
               dotags(1);
               clstags();
               flo->retstt=usrptr->substt;
               btuclo(usrnum);
               if (!isripu()) {
                    setmbk(flmsg);
                    prfmsg(CLRSCN);
                    rstmbk();
               }
               rstrxf();
               echonu(usrnum);
               btutrg(usrnum,0);
               submit(flo->tags[flo->hold].libname,
                      flo->tags[flo->hold].filname,flo->lrange,tagd,0);
               if (usrptr->state == flstt) {
                    unbreak();
                    btutrg(usrnum,255);
               }
               else {
                    return(1);
               }
          }
          else {
               if (tagd == DOWNLOD) {
                    flo->retstt=usrptr->substt;
                    prfmsg(usrptr->substt=POPWIN3);
               }
               else {
                    flo->retstt=usrptr->substt;
                    prfmsg(usrptr->substt=POPWIN2);
               }
          }
     }
     else if (sameas(stg,"%")) {
          flo->retstt=usrptr->substt;
          if (!dlfrom(flo->tags[flo->hold].libname)) {
               dlcant();
          }
          else if (candlnow(flo->tags[flo->hold].libname,
                   flo->tags[flo->hold].filname) > 0) {
               dotags(1);
               clstags();
               flo->retstt=usrptr->substt;
               btuclo(usrnum);
               prfmsg(CLRSCN);
               rstrxf();
               echonu(usrnum);
               btutrg(usrnum,0);
               submit(flo->tags[flo->hold].libname,
                      flo->tags[flo->hold].filname,flo->lrange,DOWNLOD,0);
               if (usrptr->state == flstt && usrptr->substt != LOGOFF2) {
                    unbreak();
                    btutrg(usrnum,255);
               }
               return(1);
          }
          else {
               prfmsg(usrptr->substt=POPWIN1);
          }
     }
     else if (sameas(stg,"@")) {
          setfull(totags >= (maxtags-1));
          if (flo->tdline[flo->hold] > 0) {
               if (!(flo->flags&FULLTAG)) {
                    if (dlfrom(flo->tags[flo->hold].libname)) {
                         if (!alrtag(flo->tags[flo->hold].libname,
                            flo->tags[flo->hold].filname)) {
                              flo->tagcnt++;
                         }
                         prfmsg(ENTRETRU);
                         flo->tdline[flo->hold]=-flo->tdline[flo->hold];
                    }
                    else {
                         dlcant();
                    }
               }
          }
          else {
               flo->tdline[flo->hold]=-flo->tdline[flo->hold];
               tagd=alrtag(flo->tags[flo->hold].libname,
                  flo->tags[flo->hold].filname);
               if (tagd == 0) {
                    flo->tagcnt--;
               }
               else {
                    ftag=tagoff(--tagd);
                    for (loop=0 ; loop < ftuptr->numftg ; loop++) {
                         ftgptr=&ftgusr[loop];
                         if (ftag == spc) {
                              untag(loop);
                              removetg(loop--);
                         }
                    }
                    ftag->status=-ftag->status;
               }
               prfmsg(ENTRETRN);
          }
          setfull(totags >= (maxtags-1));
     }
     else if (sameas(stg,"x") || sameas(stg,"!")) {
          btupbc(usrnum,0);
          rebuild(1);
          unbreak();
          usrptr->substt=FILELST0;
     }
     else {
          prfmsg(BEEP);
     }
     return(0);
}

INT
iviewasc(                          /* view a file info, ascii              */
CHAR chr)
{
     INT loop,flag;

     flag=flo->hold;
     cncall();
     switch (chr) {
     case 'X':
     case '\0':
          usrptr->substt=FILELST1;
          break;
     case 'T':
          if (flo->tdline[flag] != 0) {
               setfull(totags >= (maxtags-1));
               if (!dlfrom(flo->tags[flag].libname)) {
                    prfmsg(NOAXSFIL);
               }
               else if (flo->tdline[flag] > 0) {
                    if (!(flo->flags&FULLTAG)) {
                         if (!alrtag(flo->tags[flag].libname,
                            flo->tags[flag].filname)) {
                              flo->tagcnt++;
                         }
                         prfmsg(ATAGGED,flo->tags[flag].filname);
                         flo->tdline[flag]=-flo->tdline[flag];
                    }
               }
               else {
                    flo->tdline[flag]=-flo->tdline[flag];
                    loop=alrtag(flo->tags[flag].libname,
                       flo->tags[flag].filname);
                    if (loop == 0) {
                         flo->tagcnt--;
                    }
                    else {
                         ftag=tagoff(--loop);
                         for (loop=0 ; loop < ftuptr->numftg ; loop++) {
                              ftgptr=&ftgusr[loop];
                              if (ftag == spc) {
                                   untag(loop);
                                   removetg(loop--);
                              }
                         }
                    }
                    setfull(0);
                    prfmsg(AUNTAGED,flo->tags[flag].filname);
               }
               setfull(totags >= (maxtags-1));
          }
          usrptr->substt=FILELST1;
          break;
     case 'D':
          if (!dlfrom(flo->tags[flag].libname)) {
               prfmsg(NOAXSFIL);
               usrptr->substt=FILELST1;
          }
          else if (candlnow(flo->tags[flag].libname,
             flo->tags[flag].filname) > 0) {
               flo->retstt=usrptr->substt;
               btuclo(usrnum);
               submit(flo->tags[flag].libname,flo->tags[flag].filname,
                flo->lrange,DOWNLOD,0);
               if (usrptr->state != flstt) {
                    rstrxf();
               }
               return(1);
          }
          break;
     case 'V':
          if (!dlfrom(flo->tags[flag].libname)) {
               prfmsg(NOAXSFIL);
               usrptr->substt=FILELST1;
          }
          else if ((loop=candlnow(flo->tags[flag].libname,
             flo->tags[flag].filname)) > DOWNLOD) {
               dotags(1);
               clstags();
               flo->retstt=usrptr->substt;
               btuclo(usrnum);
               prfmsg(CLRSCN);
               outprf(usrnum);
               submit(flo->tags[flag].libname,flo->tags[flag].filname,
                  flo->lrange,loop,0);
               if (usrptr->state != flstt) {
                    rstrxf();
               }
               return(1);
          }
     }
     return(0);
}

VOID
ifilistx(                          /* main search input handler, non-ansi  */
CHAR *stg)
{
     CHAR chr;
     INT loop;
     struct fllib *libptr;

     chr=toupper(*stg);
     for (loop=0 ; loop < NLISTER ; loop++) {
          if (sameas(stg,flo->tags[loop].filname)) {
               chr='A'+loop;
          }
     }
     if (flo->atend&LSTNONE) {
          chr='X';
     }
     switch (chr) {
     case '\0':
          if (!(flo->atend&LSTBACK)) {
               if (!srcincx()) {
                    dotags(0);
                    dispfhdr(2);
                    flo->tagk='A'-1;
                    wipetag();
                    flo->flags&=~STOPLST;
                    return;
               }
               else {
                    usrptr->substt=FILELST2;
               }
          }
          else {
               prfmsg(BTWEND);
               return;
          }
          break;
     case 'X':
          exitview();
          cncall();
          return;
     case 'R':
          rebuild(0);
          usrptr->substt=FILELST1;
          break;
     case '?':
          prfmsg(FILEHELA);
          break;
     }
     if (chr >= 'A' && chr < ('A'+NLISTER)) {
          flo->hold=chr-'A';
          if (flo->tdline[flo->hold] != 0) {
               libptr=libfind(flo->tags[flo->hold].libname);
               if (libptr == NULL || !(libptr->flags&FLGDOS)) {
                    buildview(flo->hold);
               }
               usrptr->substt=VIEWASC;
               return;
          }
     }
}

INT
ifilist(                           /* main search input handler            */
CHAR *stg)
{
     INT flag,loop,stags;
     CHAR chr;

     if (*stg == '\0') {
          return(0);
     }
     chr=toupper(*stg);
     if (chr >= 'A' && chr < ('A'+NLISTER)) {
          if (!isripu() || flo->cursor != chr-'A') {
               if (flo->tdline[chr-'A'] != 0) {
                    curspos(chr-'A');
               }
               else {
                    prfmsg(BEEP);
               }
               flo->flags|=DBLCLCK;
               return(0);
          }
          else if (flo->flags&DBLCLCK) {
               chr='@';
          }
          else {
               flo->flags|=DBLCLCK;
               return(0);
          }
     }
     flo->flags&=~DBLCLCK;
     if (chr == '@') {
          stags=totags;
          setfull(totags >= (maxtags-1));
          if (flo->tdline[flo->cursor] > 0) {
               if (!(flo->flags&FULLTAG)) {
                    if (dlfrom(flo->tags[flo->cursor].libname)) {
                         if (!alrtag(flo->tags[flo->cursor].libname,
                            flo->tags[flo->cursor].filname)) {
                              flo->tagcnt++;
                         }
                         if (stags == 0) {
                              prfmsg(CTRLT);
                         }
                         prfmsg(TAGGED,flo->tdline[flo->cursor]+3,
                            'A'+flo->cursor);
                         flo->tdline[flo->cursor]=-flo->tdline[flo->cursor];
                    }
                    else {
                         dlcant();
                    }
               }
               else {
                    prfmsg(BEEP);
                    if (flo->flags&USRANSI) {
                         prfmsg(usrptr->substt=POPWIN7);
                    }
               }
          }
          else if (flo->tdline[flo->cursor] < 0) {
               flo->tdline[flo->cursor]=-flo->tdline[flo->cursor];
               loop=alrtag(flo->tags[flo->cursor].libname,
                  flo->tags[flo->cursor].filname);
               if (loop == 0) {
                    flo->tagcnt--;
               }
               else {
                    ftag=tagoff(--loop);
                    for (loop=0 ; loop < ftuptr->numftg ; loop++) {
                         ftgptr=&ftgusr[loop];
                         if (ftag == spc) {
                              untag(loop);
                              removetg(loop--);
                         }
                    }
                    ftag->status=-ftag->status;
               }
               setfull(0);
               prfmsg(UNTAGGED,flo->tdline[flo->cursor]+3,'A'+flo->cursor);
               if (totags == 0) {
                    prfmsg(CLRCTRLT);
               }
          }
          setfull(totags >= (maxtags-1));
          return(0);
     }
     if (chr == '?') {
          prfmsg((flo->flags&STOPLST) ? usrptr->substt=FILHELP : BEEP);
          return(0);
     }
     if (chr == '!') {
          chr='A'+flo->cursor;
          if (chr >= 'A' && chr < ('A'+NLISTER)) {
               flag=chr-'A';
               if (flo->tdline[flag] != 0) {
                    if (flo->keymeth == 9) {
                         flo->retstt=usrptr->substt;
                         prfmsg((flo->flags&STOPLST) ? usrptr->substt=POPWIN4
                    : BEEP);
                    }
                    else {
                         btupbc(usrnum,0);
                         buildview(flag);
                         unbreak();
                         flo->hold=flag;
                    }
               }
               else {
                    prfmsg(BEEP);
               }
          }
          return(0);
     }
     if (chr == '<') {
          curspos(flo->cursor-1);
          return(0);
     }
     if (chr == '>') {
          curspos(flo->cursor+1);
          return(0);
     }
     if (chr == ')') {
          curspos(-1);
          return(0);
     }
     if (chr == '(') {
          curspos(0);
          return(0);
     }
     if (chr == '-' && (flo->atend == LSTFILS || flo->atend == LSTBACK)) {
          if (!srcincx()) {
               flo->flags|=REVSRCH;
               flo->flags&=~STOPLST;
               rset();
               dotags(1);
               dispfhdr(2);
               flo->tagk='A'-1;
               wipetag();
               newpage();
          }
          return(0);
     }
     if (chr == '+' && (flo->atend == LSTFILS || flo->atend == LSTFORE)) {
          if (!srcincx()) {
               flo->flags&=~REVSRCH;
               flo->flags&=~STOPLST;
               rset();
               dotags(1);
               dispfhdr(2);
               flo->tagk='A'-1;
               wipetag();
               newpage();
          }
          return(0);
     }
     flo->hold=flo->cursor;
     if (sameas(stg,"&")) {
          if (flo->tdline[flo->hold] == 0) {
               prfmsg(BEEP);
               return(0);
          }
          if (!dlfrom(flo->tags[flo->hold].libname)) {
               dlcant();
          }
          else if ((flag=candlnow(flo->tags[flo->hold].libname
                      ,flo->tags[flo->hold].filname)) > DOWNLOD) {
               dotags(1);
               clstags();
               flo->retstt=usrptr->substt;
               btuclo(usrnum);
               if (!isripu()) {
                    setmbk(flmsg);
                    prfmsg(CLRSCN);
                    rstmbk();
               }
               rstrxf();
               echonu(usrnum);
               btutrg(usrnum,0);
               submit(flo->tags[flo->hold].libname,
                      flo->tags[flo->hold].filname,flo->lrange,flag,0);
               if (usrptr->state == flstt) {
                    unbreak();
                    btutrg(usrnum,255);
               }
               return(1);
          }
          else {
               if (flag == 1) {
                    flo->retstt=usrptr->substt;
                    prfmsg((flo->flags&STOPLST) ? usrptr->substt=POPWIN3
                  : BEEP);
               }
               else {
                    flo->retstt=usrptr->substt;
                    prfmsg((flo->flags&STOPLST) ? usrptr->substt=POPWIN2
                  : BEEP);
               }
          }
     }
     else if (sameas(stg,"%")) {
          flo->retstt=usrptr->substt;
          dotags(1);
          clstags();
          if (flo->tdline[flo->hold] == 0) {
               prfmsg(BEEP);
               return(0);
          }
          if (!dlfrom(flo->tags[flo->hold].libname)) {
               dlcant();
          }
          else if (candlnow(flo->tags[flo->hold].libname
                      ,flo->tags[flo->hold].filname) > 0) {
               btuclo(usrnum);
               prfmsg(CLRSCN);
               outprf(usrnum);
               rstrxf();
               echonu(usrnum);
               btutrg(usrnum,0);
               submit(flo->tags[flo->hold].libname,
                      flo->tags[flo->hold].filname,flo->lrange,DOWNLOD,0);
               if (usrptr->state == flstt && usrptr->substt != LOGOFF3) {
                    unbreak();
                    btutrg(usrnum,255);
               }
               return(1);
          }
          else {
               prfmsg((flo->flags&STOPLST) ? usrptr->substt=POPWIN1 : BEEP);
          }
     }
     else if (sameas(stg,"#")) {
          dotags(1);
          clstags();
          if (ftuptr->numftg > 0) {
               flo->flags|=OFTGMAN;
               flo->retstt=usrptr->substt;
               usrptr->substt=TAGMAN;
               echonu(usrnum);
               btutrg(usrnum,0);
               btuclo(usrnum);
               prfmsg(CLRSCN);
               prfmsg(DEFRIPM);
               outprf(usrnum);
               prf("");
          }
          else if (isripu()) {
               prfmsg(BEEP);
          }
          return(0);
     }
     else if (sameas(stg,"x")) {
          exitview();
     }
     else {
          prfmsg(BEEP);
     }
     return(0);
}

VOID
itranspr(                          /* default transfer protocol            */
CHAR chr)
{
     if ((chr == '\0') || (chr == '?') || (chr == '.')) {
          strcpy(flu->proto,"?");
     }
     else if (chr == 'X') {
          cncall();
          usrptr->substt=PREFERS;
          return;
     }
     else if (valdpc(spr("%c",chr)) && chr != 'T') {
          stzcpy(flu->proto,spr("%c%c",chr,
                 ((chr == 'Z') && (morcnc() == 'R')) ? 'R' : '\0'),3);
          if ((chr == 'Z') && (morcnc() == 'R')) {
               cncchr();
          }
          if ((chr == 'M') || (chr == 'C') || (chr == '1') || (chr == 'F')) {
               prfmsg(PROTNOTE);
          }
     }
     else {
          cncall();
          prfmsg(INVALPRT);
          return;
     }
     if (sameas(flu->proto,defproto)) {
          setmem(flu->proto,3,0);
     }
     if ((flu->proto[0] == '\0' && sameas(defproto,"?"))
      || sameas(flu->proto,"?")) {
          flu->askme=0;
          usrptr->substt=PREFERS;
          cncall();
     }
     else {
          usrptr->substt=ASKOFF;
     }
     updusr(flu);
}

VOID
irename(                           /* rename or maybe overwrite            */
CHAR *stg)
{
     struct ffblk fb;
     INT who;
     struct taglib *tag;
     INT loop;

     if (sameas(stg,"x")) {
          unlink(flo->srcpath);
          if (flo->dodesc != NEVRASK) {
               flo->dodesc=ASKDESC;
          }
          if (ulfileq(0)) {
               usrptr->substt=AUTOLOG;
               btuinj(usrnum,CYCLE);
          }
          else {
               doneLog(FALSE);
          }
          return;
     }
     if (sameas(stg,"*")) {
          if ((who=w2writ(curlib->libname,flo->miscfil,0)) != NOCONFLICT
           && who != usrnum) {
               prfmsg(OVERCFL,curlib->libname,
                              flo->miscfil,uacoff(who)->userid);
               return;
          }
          for (loop=0 ; loop < systags ; loop++) {
               tag=tagoff(loop);
               if (tag->status > TGEMPTY && tag->usrnum != usrnum
                && sameas(tag->filname,flo->miscfil)
                && sameas(tag->libname,curlib->libname)) {
                    prf("\rAnother user "
                        "has this file, %s, tagged for download!\r",
                        flo->miscfil);
                    return;
               }
          }
          dfaSetBlk(flfdat);
          if (dfaAcqEQ(NULL,compkey(curlib->libname,flo->miscfil),COMPLF)
           && usrptr->substt == RENAMO && ucanovw(curlib,flf)) {
               stzcpy(flo->key1.libname,curlib->libname,FLNAMESZ);
               stzcpy(flo->key1.filname,flo->miscfil,FLFILENM);
               if ((flo->fsrc=fopen(flo->srcpath,FOPRB)) != NULL) {
                    if ((flo->fdst=fopen(flo->destpath,FOPWB)) != NULL) {
                         if (fndfile(&fb,flo->srcpath,0)) {
                              curlib->totbytes-=flclfit(flf->siz,
                                                        curlib->cluster);
                              flf->siz=fb.ff_fsize;
                              curlib->totbytes+=flclfit(flf->siz,
                                                        curlib->cluster);
                              if (notapped(flf->udate)) {
                                   curlib->appwait--;
                              }
                              chuldate(curlib,flf->udate,0);
                              if (!notapped(flf->udate)
                               || haslibkey(curlib,curlib->autoap)) {
                                   stzcpy(flf->udate,ddat2srt(today()),DATESZ);
                              }
                              chuldate(curlib,flf->udate,1);
                              if (notapped(flf->udate)) {
                                   curlib->appwait++;
                              }
                              flf->utime=now();
                              stzcpy(flf->fdate,ddat2srt(fb.ff_fdate),DATESZ);
                              flf->tim=fb.ff_ftime;
                              stzcpy(flf->ulby,usaptr->userid,UIDSIZ);
                              dfaUpdateV(NULL,FLFILREC+strlen(flf->desc)+1);
                              prfmsg(usrptr->substt=COPYING);
                              btuinj(usrnum,CYCLE);
                              flo->retstt=AUTOLOG;
                              curlib->flags|=LIBCHN;
                              return;
                         }
                         fclose(flo->fdst);
                         flo->fdst=NULL;
                    }
                    fclose(flo->fsrc);
                    flo->fsrc=NULL;
               }
          }
          prfmsg(CANTOVER);
     }
     else if (okfname(stg)
           && rename(flo->srcpath,spr("%s"SLS"%s",userdir(1),stg)) == 0) {
          usrptr->substt=AUTOLOG;
          flo->miscfil[0]='\0';
          btuinj(usrnum,CYCLE);
     }
     else if (stg[0] != '\0') {
          prfmsg(CANTRNAM);
     }
}

VOID
ichain(                            /* manage joining libs                  */
CHAR chr)
{
     switch (chr) {
     case '\0':
     case 'X':
          retmenu(1);
          break;
     case '?':
          prfmsg(CHAINHLP);
          flo->retstt=usrptr->substt;
          usrptr->substt=PRESENTR;
          break;
     case 'L':
          prfmsg(CHAINLST);
          listjoin();
          flo->retstt=usrptr->substt;
          usrptr->substt=PRESENTR;
          break;
     case 'J':
          flo->index=0;
          usrptr->substt=CHUNJ;
          break;
     case 'U':
          scanlib(0,curlib);
          if (chjoined(curlib,curlib->libname)) {
               curlib->libs--;
          }
          if (curlib->libs == 0) {
               prfmsg(CHAINO);
          }
          else {
               flo->index=1;
               usrptr->substt=CHUNJ;
          }
          break;
     case 'S':
          if (flo->nlibaxs > 1) {
               usrptr->substt=SELLIB3;
          }
          else {
               prfmsg(NOOLIB);
          }
     }
}

VOID
ijoin(                             /* join inputted Library up             */
CHAR *stg)
{
     struct fllib *libptr;

     if (stg[0] == '\0' || sameas(stg,"x")) {
          usrptr->substt=CHAINMNU;
     }
     else {
          libptr=libfind(stg);
          if (libptr == NULL) {
               prfmsg(CHNOS);
          }
          else if (libptr == curlib) {
               prfmsg(NOJNSELF);
          }
          else if (libptr->flags&FLGDOS) {
               prfmsg(NOJNDOS);
          }
          else {
               if (chjoin(curlib,libptr,flo->index)) {
                    prfmsg(flo->index ? CHUJOIN : CHJOIN);
                    scanlibs();
               }
               else {
                    prfmsg(flo->index ? CHUJOINX : CHJOINX);
               }
          }
     }
}

VOID
iflblist(                          /* create a list of libs menu           */
CHAR chr)
{
     INT all,multi=0;

     if (chr == 'X' || chr == '\0') {
          retmenu(0);
     }
     if (chr == 'A') {
          all=1;
     }
     else if (chr == 'C') {
          all=0;
     }
     else {
          return;
     }
     while (morcnc() == ' ') {
          cncchr();
     }
     stzcpy(flo->savprot,cncall(),3);
     flo->flags|=AXSUSER;
     flo->fsrc=fopen(spr("%s"SLS"%s.X%02X",copydir,(all ? "FILES!" :
                                        curlib->libname),
                channel[usrnum]),FOPWA);
     if (flo->fsrc == NULL) {
          prfmsg(FLBERR);
          return;
     }
     wipetag();
     flo->styp=3;
     setmem(flo->keylist,FLKEYLST,0);
     setmem(&flo->u,sizeof(union combo),0);
     if (!all) {
          if (scanlib(1,curlib)) {
               multi=1;
          }
          scanlib(0,curlib);
     }
     clrprf();
     flo->flags&=~REVSRCH;
     if (all || multi) {
          flo->keymeth=4;
          stzcpy(flo->u.key4.libname,all ? "" : curlib->libname,FLNAMESZ);
          setmem(flo->u.key4.filname,FLFILENM,0);
     }
     else {
          flo->keymeth=1;
          stzcpy(flo->u.key1.libname,curlib->libname,FLNAMESZ);
          setmem(flo->u.key1.filname,FLFILENM,0);
     }
     prfmsg(all ? LSTHDRA : LSTHDRB ,all ? "" : curlib->libname);
     if (all) {
          flo->flags|=LISTALL;
     }
     else {
          flo->flags&=~LISTALL;
     }
     if (isansiu()) {
          flo->flags|=USRANSI;
     }
     else {
          flo->flags&=~USRANSI;
     }
     if (!(flo->flags&USRANSI) || stplist) {
          stpans(prfbuf);
     }
     strcrep(prfbuf,13,10);
     fprintf(flo->fsrc,"%s",prfbuf);
     clrprf();
     if (initsrc()) {
          flo->retstt=LSTCYC;
          prfmsg(usrptr->substt=CYCIDX);
     }
     else {
          prfmsg(usrptr->substt=LSTCYC);
     }
     btuinj(usrnum,CYCLE);
}

INT
inpfunc(VOID)                      /* the big status3-input function       */
{
     INT retval=1;
     CHAR *stg,chr,*path;

     switch (usrptr->substt) {
     case CYCIDX:
          break;
     case PLSWAIT:
          if (sameas(cncall(),"x")) {
               retmenu(0);
          }
          break;
     case AUTOGONE:
          prfmsg(BANGAVT);
          retmenu(0);
          break;
     case TAGSTAT:
          prfmsg(CLRSCN);
          retmenu(1);
          break;
     case LSTCYC:
          if (flo->fsrc != NULL) {
               fclose(flo->fsrc);
               flo->fsrc=NULL;
          }
          prfmsg(LSTABT);
          retmenu(0);
          break;
     case FLBLIST:
          iflblist(cncchr());
          break;
     case WLDSYS:
     case WLDSRCH:
          flo->wtnum=-(flo->wtnum+1);
          break;
     case INDDELK:
          break;
     case RESOLVE:
          break;
     case CLIBNAM:
          iclibnam(cncall());
          break;
     case DOSO:
          idoso(cncchr());
          break;
     case VIEWASC:
          if (morcnc() == ' ') {
               cncchr();
          }
          if (iviewasc(cncchr())) {
               return(2);
          }
          break;
     case POPWIN6:
          exitview();
          break;
     case POPWIN1:
     case POPWIN2:
     case POPWIN3:
     case POPWIN4:
     case POPWIN5:
     case POPWIN7:
     case FILHELP:
          if (cncall()[0] != '\0') {
               if (usrptr->substt == FILHELP) {
                    prtbuild(1,14);
                    usrptr->substt=FILELST0;
               }
               else if (flo->retstt == ENTRETT) {
                    usrptr->substt=ENTRETT;
                    buildview(flo->hold);
               }
               else {
                    prtbuild(5,6);
                    usrptr->substt=FILELST0;
               }
          }
          break;
     case RENNAME:
          if ((stg=cncall())[0] == '\0' || sameas(stg,"x")) {
               usrptr->substt=DELMENU;
          }
          else if (sameas(stg,flo->miscfil)) {
               prfmsg(INVALFN);
          }
          else if (okfname(fnmcse(stg))) {
               path=(strlen(curlib->path) ? curlib->path : curlib->libname);
               if (rename(spr("%s"SLS"%s",path,flo->miscfil),
                          spr("%s"SLS"%s",path,stg)) != 0) {
                    prfmsg(INVALFN);
               }
               else {
                    dfaSetBlk(flfdat);
                    if (dfaAcqEQ(NULL,compkey(curlib->libname,flo->miscfil),
                                 COMPLF)) {
                         stzcpy(flf->filname,stg,FLFILENM);
                         stzcpy(flo->destpath,stg,FLFILENM);
                         dfaUpdateV(NULL,FLFILREC+strlen(flf->desc)+1);
                    }
                    prfmsg(RENAMED);
                    if (!longsrch) {
                         usrptr->substt=RENCYC;
                         btuinj(usrnum,CYCLE);
                    }
                    else {
                         usrptr->substt=DELMENU;
                    }
               }
          }
          else {
               prfmsg(INVALFN);
          }
          break;
     case RENCYC:
          break;
     case UNAPPING:
     case APPING:
          retmenu(1);
          break;
     case DELLIB:
          break;
     case FILMOVA:
          break;
     case CHAINMNU:
          ichain(cncchr());
          break;
     case CHUNJ:
          ijoin(cncall());
          break;
     case ENTUADNM:
          ienuadnm(cncwrd());
          break;
     case FLSTYPA:
          iflstyp(cncchr());
          break;
     case FLSLIB:
          iflslib(cncchr());
          break;
     case ASKWORD:
          iaskword(cncall());
          break;
     case ASKNAME:
          iaskname(cncwrd());
          break;
     case FDESCED:
          if (ifdesced(cncall())) {
               return(2);
          }
          break;
     case PREFERS:
          iprefers(cncchr());
          break;
     case RENAME:
     case RENAMO:
     case BADNAME:
          irename(cncall());
          break;
     case MMENU:
          if (strlen(nxtcmd) > 1) {
               switch (toupper(*nxtcmd)) {
               case 'S':
                    if (sameto("s?",nxtcmd)) {
                         prfmsg(DEFRIPM);
                         outprf(usrnum);
                         prf("");
                    }
                    else if (!sameto("s ",nxtcmd)) {
                         usrptr->flags&=~CONCEX;
                    }
                    else if (sameto("s ?",nxtcmd)) {
                         cncall();
                         flo->index=0;
                         flo->retstt=usrptr->substt;
                         usrptr->substt=LIBLST;
                         prfmsg(DEFRIPM);
                         prfmsg(LIBLST);
                         outprf(usrnum);
                         prf("");
                         btuinj(usrnum,CYCLE);
                         return(1);
                    }
                    break;
               }
          }
          retval=lsmenu();
          break;
     case MANAGMNU:
          imanmnu(cncchr());
          break;
     case BIGCPY:
          break;
     case AUTOLOG:
          break;
     case BIGCOPY:
          ibigcopy(cncall());
          break;
     case WARNMARK:
          iwarnmrk(cncall());
          break;
     case SEARCHEM:
          prfmsg(SEARCHAB);
          retmenu(1);
          break;
     case DELFIL:
          idelfil(cncall());
          break;
     case FILDELA:
     case FILDELB:
          setmisc("0");
          flo->retstt=DELMENU;
          ftgdnl("-ALL",retoinl);
          setmisc("");
          return(2);
     case APPMENU:
          iappmenu(cncchr());
          break;
     case DELMENU:
          idelmenu(cncchr());
          break;
     case MOVMENU:
          imovmenu(cncchr());
          break;
     case MOVPATH:
          imovpath(cncall());
          break;
     case UNAPPMNU:
          iunapp(cncchr());
          break;
     case OPMENU:
          switch (retval=oprmenu()) {
          case 2:
               return(2);
          case 0:
               retmenu(0);
          default:
               retval=1;
          }
          break;
     case LIBLST:
          usrptr->substt=flo->retstt;
     case SELLIB:
     case SELLIB2:
     case SELLIB3:
          retval=isellib(cnclib());
          break;
     case LIBEDTN:
          break;
     case DELLIBNM:
          if (idellibn(cnclib())) {
               return(2);
          }
          break;
     case PRESENTR:
          switch (usrptr->substt=flo->retstt) {
          case FILELST0:
               rebuild(1);
               btutrg(usrnum,255);
               btuinj(usrnum,CYCLE);
               break;
          case ENTRETT:
               unbreak();
               buildview(flo->hold);
               btutrg(usrnum,255);
               break;
          case PRESENTR:
          case MMENU:
               retmenu(0);
               break;
          case OPMENU:
               retmenu(1);
               break;
          case AUTOLOG:
               btuinj(usrnum,CYCLE);
          }
          break;
     case ENTDLFIL:
          if (ientdl(cncwrd())) {
               return(2);
          }
          break;
     case TAGMAN:
          if (itagman(cncwrd())) {
               return(2);
          }
          break;
     case ASKWHLPA:
     case ASKWHLPB:
     case ASKWHLPC:
          if (sameas(cncall(),"x")) {
               usrptr->substt=ASKWORD;
          }
          else {
               switch (usrptr->substt) {
               case ASKWHLPA:
                    prfmsg(usrptr->substt=ASKWHLPB);
                    break;
               case ASKWHLPB:
                    prfmsg(usrptr->substt=ASKWHLPC);
                    break;
               case ASKWHLPC:
                    usrptr->substt=ASKWORD;
               }
          }
          break;
     case LOGOFF:
          if (sameas((stg=cncall()),"x")) {
               usrptr->substt=TAGMAN;
               break;
          }
          if (sameas(stg,"?")) {
               break;
          }
          dnlstart(lingyn(*stg) == 'Y');
          outprf(usrnum);
          return(2);
     case LOGOFF2:
     case LOGOFF3:
          if (sameas((stg=cncall()),"x")) {
               usrptr->state=0;
               retoin();
               return(2);
          }
          if (sameas(stg,"?")) {
               break;
          }
          dnlstart(lingyn(*stg) == 'Y');
          outprf(usrnum);
          return(2);
     case OVERW:
          if (ioverw(cncyesno())) {
               return(2);
          }
          break;
     case ENTULFIL:
          if (ientul(cncwrd())) {
               return(2);
          }
          break;
     case ULMOD:
          if (iulmod(cncall())) {
               return(2);
          }
          break;
     case COPYING:
          break;
     case DIZZYING:
          break;
     case KEYWORDY:
          break;
     case ENTRETT:
          if (ientret(cncall())) {
               return(2);
          }
          break;
     case FILELST2:
     case FILELST1:
          ifilistx(cncwrd());
          break;
     case FILELST0:
          if (ifilist(cncall())) {
               return(2);
          }
          break;
     case TRANSPRT:
          itranspr(cncchr());
          break;
     case ASKOFF:
          chr=cncyesno();
          cncall();
          if (lingyn(chr) == 'Y') {
               flu->askme=1;
               updusr(flu);
          }
          else if (chr != 'X') {
               flu->askme=0;
               updusr(flu);
          }
          usrptr->substt=PREFERS;
          break;
     case ASKTYPA:
          chr=cncchr();
          cncall();
          if (chr == 'X' || chr == 'X') {
               usrptr->substt=PREFERS;
               break;
          }
          switch (chr) {
          case 'P':
               flu->mytyp=1;
               break;
          case 'D':
               flu->mytyp=2;
               break;
          case 'F':
               flu->mytyp=3;
               break;
          case 'K':
               flu->mytyp=4;
               break;
          case 'N':
               flu->mytyp=5;
               break;
          case 'W':
               flu->mytyp=6;
               break;
          case 'Q':
               flu->mytyp=7;
               break;
          default:
               return(1);
          }
          usrptr->substt=PREFERS;
          updusr(flu);
          break;
     case ASKLIB:
          chr=cncchr();
          cncall();
          if (chr == '\0' || chr == 'X') {
               usrptr->substt=PREFERS;
               break;
          }
          switch (chr) {
          case 'P':
               flu->mylib=1;
               usrptr->substt=PREFERS;
               break;
          case 'C':
               flu->mylib=2;
               usrptr->substt=PREFERS;
               break;
          case 'A':
               flu->mylib=3;
               usrptr->substt=PREFERS;
          }
          if (usrptr->substt == PREFERS) {
               updusr(flu);
          }
          break;
     case DODESC:
          chr=cncchr();
          cncall();
          if (chr != '\0') {
               if (chr == '?') {
                    prfmsg(DESCHELP);
               }
               else {
                    flo->dodesc=(lingyn(chr) == 'Y' ? DOADESC :
                       (chr == 'X' ? NEVRASK : NIXDESC));
                    unbreak();
                    usrptr->substt=AUTOLOG;
                    btuinj(usrnum,CYCLE);
               }
          }
          break;
     default:
          retmenu(0);
     }
     return(retval);
}

INT
editgo(                            /* begin editing ul file descrp.        */
CHAR *filen)
{
     struct ffblk fb;
     CHAR *dir,*udate;

     dir=userdir(1);
     if (filen[0] == '\0') {
          if (!fndfile(&fb,spr("%s"SLS STAR,dir),0)) {
               return(0);
          }
     }
     else if (!fndfile(&fb,spr("%s"SLS"%s",dir,filen),0)) {
          return(0);
     }
     udate=(haslibkey(curlib,curlib->autoap) ? ddat2srt(today()) : NOTAPPED);
     return(insfile(curlib,dir,&fb,udate,usaptr->userid,""));
}

INT
writable(                          /* is Library writable?                 */
struct fllib *libptr)
{
     return(!(libptr->flags&FLGRDO) && !(libptr->flags&FLGCBD));
}

INT
lsmenu(VOID)                      /* main menu choice handler             */
{
     flo->flags&=~OFTGMAN;
     switch (cncchr()) {
     case 'O':
          if (isflop(curlib)) {
               deresume();
               prfmsg(DEFRIPM);
               flo->flags|=RETUOPM;
               usrptr->substt=OPMENU;
               return(1);
          }
          break;
     case 'P':
          prfmsg(DEFRIPM);
          usrptr->substt=PREFERS;
          return(1);
     case 'D':
          if (dlfroml(curlib)) {
               prfmsg(DEFRIPM);
               usrptr->substt=ENTDLFIL;
               return(1);
          }
          break;
     case 'T':
          if (ftuptr->numftg > 0) {
               prfmsg(DEFRIPM);
               usrptr->substt=TAGMAN;
               flo->retstt=TAGMAN;
               return(1);
          }
          break;
     case 'L':
          if (haskey(listkey) && !(curlib->flags&FLGDOS)) {
               deresume();
               usrptr->substt=FLBLIST;
               return(1);
          }
          break;
     case 'U':
          if (haslibkey(curlib,curlib->ulkey) && writable(curlib)) {
               deresume();
               prfmsg(DEFRIPM);
               flo->flags&=~RETUOPM;
               flo->miscflag=0;
               if (ulfileq(0)) {
                    flo->miscfil[0]='\0';
                    flo->dodesc=ASKDESC;
                    usrptr->substt=AUTOLOG;
                    btuinj(usrnum,CYCLE);
               }
               else {
                    usrptr->substt=ENTULFIL;
               }
               return(1);
          }
          break;
     case 'S':
          if (flo->nlibaxs > 1) {
               prfmsg(DEFRIPM);
               usrptr->substt=SELLIB;
               return(1);
          }
          break;
     case 'F':
          if (curlib->flags&FLGDOS) {
               sprintf(flo->srcpath,"%s"SLS"files",curlib->libname);
               if (fndfile(&flo->fb,flo->srcpath,0)) {
                    flo->retstt=PRESENTR;
                    listing(flo->srcpath,retoinl);
                    return(2);
               }
               else {
                    srcinit(-1,curlib->libname);
                    return(1);
               }
          }
          prfmsg(DEFRIPM);
          dsearch(0,((flo->flags&ABOUPRF) ? 1 : flu->mytyp));
          return(1);
     case 'R':
          if (flo->tagk >= 'A' && flo->styp != 4 && flo->styp != 6
           && flo->styp != -1) {
               clstags();
               if (!isansiu()) {
                    flo->flags&=~USRANSI;
                    clstags();
                    rebuild(0);
                    usrptr->substt=FILELST1;
               }
               else {
                    flo->flags|=USRANSI;
                    setbusy();
                    btutrg(usrnum,255);
                    rebuild(1);
               }
               btuinj(usrnum,CYCLE);
               return(1);
          }
          break;
     case 'X':
          return(0);
     case '\0':
     case '?':
          prfmsg(MMHLP);
          return(1);
     }
     prfmsg(NOTCMD);
     retmenu(0);
     return(1);
}

INT
fupfil(                            /* file upload handler                  */
INT code)
{
     INT retval=0;
     CHAR *stg,*newfil;
     struct fllib *libptr=NULL;

     fluoff(usrnum);
     flo->flags|=AXSUSER;
     MKDIR(stg=userdir(1));
     switch (code) {
     case FUPPTH:
          if (flo->miscfil[0] != '\0') {
               strcpy(ftfscb->fname,flo->miscfil);
          }
          sprintf(ftfbuf,"%s"SLS"%s",stg,ftfscb->fname);
          retval=rename(spr("%s"SLS".."SLS"%s",stg,
                   ftfscb->fname),ftfbuf) ? 1 : 2;
          break;
     case FUPBEG:
          if (rsvnam(ftfscb->fname)) {
               sprintf(ftfbuf,"%s is an invalid file name.",
                       fnmcse(ftfscb->fname));
               break;
          }
          libptr=libfind(flu->lib);
          if (libptr != NULL) {
               if (libroom(libptr) <= 0L && !haskey(flsysop)) {
                    strcpy(ftfbuf,"Too many files already in this Library.");
                    break;
               }
               if (!haskey(flsysop)) {
                    ftfscb->maxbyt=byteroom;
               }
          }
          if (flo->miscfil[0] != '\0') {
               strcpy(ftfscb->fname,flo->miscfil);
          }
          sprintf(ftfbuf,"%s"SLS"%s",stg,ftfscb->fname);
          if (libptr != NULL && writable(libptr)) {
               zapcrd((libptr->flags&FLGFUL) || freeuls,0L,NULL);
               retval=1;
               if (ftuptr->flags&FTBANG) {   /* replace FTF autologoff     */
                    ftuptr->flags&=~FTBANG;
                    flo->flags|=OFFUPLD;
               }
          }
          break;
     case FUPEND:
          sprintf(ftfbuf,"%s"SLS"%s",stg,ftfscb->fname);
          if (!okfname(ftfscb->fname)) {
               if (!rename(ftfbuf,newfil=spr("%s"SLS"tmp.%03d",stg,
                  ftfscb->actfil))) {
                    strcpy(ftfscb->fname,spr("tmp.%03d",ftfscb->actfil));
                    strcpy(ftfbuf,newfil);
               }
          }
          rstcrd();
          if (flu->lib[0] != '\0') {
               libptr=libfind(flu->lib);
          }
          if (libptr != NULL && (auditall || (libptr->flags&FLGAUL))) {
               shocst("LIBRARY FILE UPLOAD","User %s uploaded %s"SLS"%s",
                      usaptr->userid,flu->lib,ftfscb->fname);
          }
          sv.uplds++;
          break;
     case FUPSKP:
          if (flu->lib[0] != '\0' && (libptr=libfind(flu->lib)) != NULL
             && (auditall || (libptr->flags&FLGAUL))) {
               shocst("LIBRARY FILE UPLOAD ABORTED",
                      "User %s aborted upld of %s"SLS"%s",
                      usaptr->userid,flu->lib,ftfscb->fname);
          }
          flo->flags&=~OFFUPLD;
          unlink(stg=spr("%s"SLS"%s",userdir(0),ftfscb->fname));
          rename(spr("%s"SLS"%s",userdir(1),ftfscb->fname),stg);
          break;
     case FUPFIN:
          retval=1;
     case FUPHUP:
          usrptr->state=flstt;
          usrptr->substt=flo->retstt;
          if (code != FUPFIN) {
               lshang();
          }
          else {
               if (ulfileq(0)) {
                    flo->miscfil[0]='\0';
                    if (flo->flags&(REUPLOD|OFFUPLD)) {
                         flo->dodesc=NEVRASK;
                    }
                    else {
                         flo->dodesc=ASKDESC;
                    }
                    usrptr->substt=AUTOLOG;
                    btuinj(usrnum,CYCLE);
               }
               else {
                    setmbk(flmsg);
                    unprop();
                    prfmsg(usrptr->substt);
                    outprf(usrnum);
                    clrprf();
                    rstmbk();
               }
          }
          btulok(usrnum,0);
          rstcrd();
     }
     return(retval);
}

INT
fparsrch(                /* parse search string, primitive to flo->keylist */
CHAR *stg)
{
     CHAR *current,*newarg;
     INT loop,loop2;

     while (strsrep(stg,"?","")) {
     }
     while (samend(stg," OR")) {
          stg[strlen(stg)-3]='\0';
     }
     while (samend(stg," AND")) {
          stg[strlen(stg)-4]='\0';
     }
     while (samend(stg," XOR")) {
          stg[strlen(stg)-4]='\0';
     }
     while (samend(stg," NOT")) {
          stg[strlen(stg)-4]='\0';
     }
     while (strsrep(stg," AND "," & ")) {
     }
     while (strsrep(stg," OR "," | ")) {
     }
     while (strsrep(stg," XOR "," ^ ")) {
     }
     while (strsrep(stg," NOT "," ! ")) {
     }
     if (sameto("NOT ",stg)) {
          strsrep(stg,"NOT ","!");
     }
     stzcpy(descedit,stg,DESCSIZ);
     strupr(descedit);
     strcrep(descedit,'&',' ');
     strcrep(descedit,'|',' ');
     strcrep(descedit,'^',' ');
     strcrep(descedit,'!',' ');
     strcrep(descedit,'(',' ');
     strcrep(descedit,')',' ');
     while (strsrep(descedit,"  "," ")) {
     }
     while (*descedit == ' ') {
          strcpy(descedit,&descedit[1]);
     }
     darsdesc(FLKEYLST/2,' ');
     if (dargc <= 0) {
          return(0);
     }
     for (loop=0 ; loop < dargc ; loop++) {
          stzcpy(&vdaptr[loop*FLKEYSIZ],dargv[loop],FLKEYSIZ);
     }
     flo->kcount=dargc;
     if (longsrch || countc(stg,'|') || countc(stg,'^') || countc(stg,'!')
      || countc(stg,'(')) {
          flo->styp=6;
     }
     if (flo->styp == 4) {
          dfaSetBlk(flkdat);
          for (loop=0 ; loop < dargc ; loop++) {
               setmem(&flo->kwdy,sizeof(struct key2),0);
               stzcpy(flo->kwdy.keyword,dargv[loop],FLKEYSIZ);
               if (!dfaAcqGE(NULL,&flo->kwdy,COMPKFL)) {
                    loop=1000;
               }
               else if (strlen(dargv[loop]) <= strlen(kyd->keyword)) {
                    if (!sameto(dargv[loop],kyd->keyword)) {
                         loop=1000;
                    }
               }
               else if (!sameto(kyd->keyword,dargv[loop])) {
                    loop=1000;
               }
          }
          if (loop >= 1000) {
               setmisc(flo->kwdy.keyword);
               prfmsg(NOWORD);
               setmisc("");
               return(0);
          }
     }
     for (loop=0 ; loop < (dargc-1) ; loop++) { /* sort by length          */
          current=dargv[loop];
          for (loop2=(loop+1) ; loop2 < dargc ; loop2++) {
               newarg=dargv[loop2];
               if (strlen(newarg) > strlen(current)) {
                    dargv[loop2]=current;
                    current=dargv[loop]=newarg;
               }
          }
     }
     stzcpy(newarg=flo->keylist,stg,FLKEYLST);
     for (loop=0 ; loop < dargc ; loop++) {
          current=dargv[loop];
          if (current[0] != '\0') {
               while (strsrep(newarg,current,"?")) {
               }
          }
     }
     do {
          loop2=0;
          while (strsrep(newarg," ","")) {
               loop2=1;
          }
          while (strsrep(newarg,"??","?&?")) {
               loop2=1;
          }
          while (strsrep(newarg,"?!","?&!")) {
               loop2=1;
          }
          while (strsrep(newarg,"&&","&")) {
               loop2=1;
          }
          while (strsrep(newarg,"!&","!")) {
               loop2=1;
          }
          while (strsrep(newarg,"&|","|")) {
               loop2=1;
          }
          while (strsrep(newarg,"|&","|")) {
               loop2=1;
          }
          while (strsrep(newarg,"&^","^")) {
               loop2=1;
          }
          while (strsrep(newarg,"^&","^")) {
               loop2=1;
          }
          while (strsrep(newarg,"!!","")) {
               loop2=1;
          }
          while (strsrep(newarg,"()","")) {
               loop2=1;
          }
          while (strsrep(newarg,"(&","(")) {
               loop2=1;
          }
          while (strsrep(newarg,"(|","(")) {
               loop2=1;
          }
          while (strsrep(newarg,"(^","(")) {
               loop2=1;
          }
          while (strsrep(newarg,"&)",")")) {
               loop2=1;
          }
          while (strsrep(newarg,"|)",")")) {
               loop2=1;
          }
          while (strsrep(newarg,"||","|")) {
               loop2=1;
          }
          while (strsrep(newarg,"^)",")")) {
               loop2=1;
          }
          while (strsrep(newarg,"^^","^")) {
               loop2=1;
          }
     } while (loop2);
     loop2=0;
     for (stg=newarg ; *stg != '\0' ; stg++) {
          if (*stg == '(') {
               loop2++;
          }
          else if (*stg == ')') {
               loop2--;
          }
          if (loop2 < 0) {
               break;
          }
     }
     if (loop2 != 0) {
          prfmsg(PARENS);
          return(0);
     }
     while (newarg[0] == '|') {
          strcpy(&newarg[0],&newarg[1]);
     }
     while (newarg[0] == '^') {
          strcpy(&newarg[0],&newarg[1]);
     }
     while (newarg[0] == '&') {
          strcpy(&newarg[0],&newarg[1]);
     }
     while (newarg[strlen(newarg)-1] == '!') {
          newarg[strlen(newarg)-1]='\0';
     }
     return(1);
}

VOID
retoin2(VOID)                      /* untag individually downloaded file   */
{
     if (usrptr->state != flstt) {
          fluoff(usrnum);
          setftu();
          untag(ftuptr->numftg);
          retoin();
     }
}

VOID
dnlstart(                          /* start d/l                            */
INT logoff)
{
     CHAR *stg,*prot;
     struct ftg tmpftg;

     stg=spr("%s%s",protocol(),logoff ? "!" : "");
     if (flo->pflg != 0 && flo->pflg <= ftuptr->numftg) {
          movmem(&ftgusr[flo->pflg-1],&tmpftg,sizeof(struct ftg));
          removetg(flo->pflg-1);
          if (ftgnew()) {
               movmem(&tmpftg,ftgptr,sizeof(struct ftg));
               ftgptr->flags&=~FTGABL;
               if (*stg == '?' || *stg == '\0') {
                    prfmsg(PROTHDR);
               }
               ftgdn1(stg,retoin2);
          }
     }
     else {
          prot=protocol();
          if (*prot == '?' || *prot == '\0') {
               prfmsg(PROTHDR);
          }
          ftgdnl(sameas(prot,"?") ? "" : stg,retoin);
     }
}

VOID
rebuild(                           /* reconstruct screen display           */
INT cls)
{
     INT loop;

     if (cls == 1) {
          unbreak();
     }
     dispfhdr((flo->flags&USRANSI) ? (cls ? -1 : 0) : 2);
     dfaSetBlk(flfdat);
     for (loop=0 ; loop < NLISTER ; loop++) {
          flo->tagk='A'-1+loop;
          if (flo->tdline[loop] != 0 && (flo->keymeth == 9
              || dfaAcqEQ(NULL,compkey(flo->tags[loop].libname,
              flo->tags[loop].filname),COMPLF))) {
               srcdrec(1);
          }
     }
     if (cls != 0) {
          srcpaus(1);
     }
     prf("[3f");
     outprf(usrnum);
     prf("");
}

VOID                               /* partial reconstruct screen display   */
prtbuild(
INT start,
INT run)
{
     INT loop;

     dispfhdr(0);
     clrprf();
     dfaSetBlk(flfdat);
     flo->tagk='A'-1;
     for (loop=0 ; loop < NLISTER ; loop++) {
          if (loop >= start) {
               prf("[%df[K",loop+4);
          }
          if (flo->tdline[loop] != 0 && (flo->keymeth == 9
             || dfaAcqEQ(NULL,compkey(flo->tags[loop].libname,
             flo->tags[loop].filname),COMPLF))) {
               srcdrec(1);
               if (loop < start) {
                    clrprf();
               }
          }
          else {
               flo->tagk++;
          }
          if (loop >= (start+run-1)) {
               break;
          }
     }
     prf("[3f");
     outprf(usrnum);
}
