home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / UTIL / WWIVSOR / XFEROVL.C < prev    next >
Text File  |  1995-04-26  |  31KB  |  1,302 lines

  1. /*****************************************************************************
  2.  
  3.                 WWIV Version 4
  4.                     Copyright (C) 1988-1995 by Wayne Bell
  5.  
  6. Distribution of the source code for WWIV, in any form, modified or unmodified,
  7. without PRIOR, WRITTEN APPROVAL by the author, is expressly prohibited.
  8. Distribution of compiled versions of WWIV is limited to copies compiled BY
  9. THE AUTHOR.  Distribution of any copies of WWIV not compiled by the author
  10. is expressly prohibited.
  11.  
  12.  
  13. *****************************************************************************/
  14.  
  15.  
  16.  
  17. #include "vars.h"
  18.  
  19. #pragma hdrstop
  20.  
  21. #include <time.h>
  22. #include <dir.h>
  23.  
  24.  
  25. /* number of dots for searching */
  26. #define DOTS 5
  27.  
  28.  
  29. #define SETREC(f,i)  sh_lseek(f,((long) (i))*((long)sizeof(uploadsrec)),SEEK_SET);
  30.  
  31. /* color for frame */
  32. #define FRAME 7
  33.  
  34. void move_file(void)
  35. {
  36.   char sx[81],s1[81],s2[81],ch,*ss;
  37.   int i,i1,ok,d1,d2,done,cp,f;
  38.   uploadsrec u,u1;
  39.  
  40.   ok=0;
  41.   nln(2);
  42.   prt(2,get_string(821));
  43.   input(sx,12);
  44.   if (strchr(sx,'.')==NULL)
  45.     strcat(sx,".*");
  46.   align(sx);
  47.   dliscan();
  48.   i=recno(sx);
  49.   if (i<0) {
  50.     nl();
  51.     pl(get_string(89));
  52.     return;
  53.   }
  54.   done=0;
  55.  
  56.   tmp_disable_conf(1);
  57.  
  58.   while ((!hangup) && (i>0) && (!done)) {
  59.     cp=i;
  60.     f=sh_open1(dlfn,O_RDONLY | O_BINARY);
  61.     SETREC(f,i);
  62.     sh_read(f,(void *)&u,sizeof(uploadsrec));
  63.     f=sh_close(f);
  64.     nl();
  65.     printfileinfo(&u,udir[curdir].subnum);
  66.     nl();
  67.     prt(5,get_string(822));
  68.     ch=ynq();
  69.     if (ch=='Q')
  70.       done=1;
  71.     else if (ch=='Y') {
  72.       sprintf(s1,"%s%s",directories[udir[curdir].subnum].path,u.filename);
  73.       do {
  74.         nln(2);
  75.         prt(2,get_string(823));
  76.         ss=mmkey(1);
  77.         if (ss[0]=='?') {
  78.           dirlist();
  79.           dliscan();
  80.         }
  81.       } while ((!hangup) && (ss[0]=='?'));
  82.       d1=-1;
  83.       if (ss[0])
  84.         for (i1=0; (i1<num_dirs) && (udir[i1].subnum!=-1); i1++)
  85.           if (strcmp(udir[i1].keys,ss)==0)
  86.             d1=i1;
  87.       if (d1!=-1) {
  88.         ok=1;
  89.         d1=udir[d1].subnum;
  90.         dliscan1(d1);
  91.         if (recno(u.filename)>0) {
  92.           ok=0;
  93.           nl();
  94.           pl(get_string(824));
  95.         }
  96.         if (numf>=directories[d1].maxfiles) {
  97.           ok=0;
  98.           nl();
  99.           pl(get_string(825));
  100.         }
  101.         if (freek1(directories[d1].path)<((double)(u.numbytes/1024L)+3)) {
  102.           ok=0;
  103.           nl();
  104.           pl(get_string(826));
  105.         }
  106.         dliscan();
  107.       } else
  108.         ok=0;
  109.     } else
  110.       ok=0;
  111.     if (ok && !done) {
  112.       prt(5,get_string(934));
  113.       if (yn()) {
  114.         time((long *)&u.daten);
  115.       }
  116.  
  117.       --cp;
  118.       f=sh_open(dlfn,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  119.       for (i1=i; i1<numf; i1++) {
  120.         SETREC(f,i1+1);
  121.         sh_read(f,(void *)&u1,sizeof(uploadsrec));
  122.         SETREC(f,i1);
  123.         sh_write(f,(void *)&u1,sizeof(uploadsrec));
  124.       }
  125.       --numf;
  126.       SETREC(f,0);
  127.       sh_read(f, &u1, sizeof(uploadsrec));
  128.       u1.numbytes=numf;
  129.       SETREC(f,0);
  130.       sh_write(f,(void *)&u1,sizeof(uploadsrec));
  131.       f=sh_close(f);
  132.       ss=read_extended_description(u.filename);
  133.       if (ss)
  134.         delete_extended_description(u.filename);
  135.  
  136.       sprintf(s2,"%s%s",directories[d1].path,u.filename);
  137.       dliscan1(d1);
  138.       f=sh_open(dlfn,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  139.       for (i=numf; i>=1; i--) {
  140.         SETREC(f,i);
  141.         sh_read(f,(void *)&u1,sizeof(uploadsrec));
  142.         SETREC(f,i+1);
  143.         sh_write(f,(void *)&u1,sizeof(uploadsrec));
  144.       }
  145.       SETREC(f,1);
  146.       sh_write(f,(void *)&u,sizeof(uploadsrec));
  147.       ++numf;
  148.       SETREC(f,0);
  149.       sh_read(f, &u1, sizeof(uploadsrec));
  150.       u1.numbytes=numf;
  151.       if (u.daten>u1.daten) {
  152.         u1.daten = u.daten;
  153.         dir_dates[d1]=u.daten;
  154.       }
  155.       SETREC(f,0);
  156.       sh_write(f,(void *)&u1,sizeof(uploadsrec));
  157.       f=sh_close(f);
  158.       if (ss) {
  159.         add_extended_description(u.filename,ss);
  160.         bbsfree(ss);
  161.       }
  162.  
  163.       if ((strcmp(s1,s2)!=0) && (exist(s1))) {
  164.         d2=0;
  165.         if ((s1[1]!=':') && (s2[1]!=':'))
  166.           d2=1;
  167.         if ((s1[1]==':') && (s2[1]==':') && (s1[0]==s2[0]))
  168.           d2=1;
  169.         if (d2) {
  170.           rename(s1,s2);
  171.           unlink(s1);
  172.         } else {
  173.           copy_file(s1,s2);
  174.           unlink(s1);
  175.         }
  176.       }
  177.       nl();
  178.       pl(get_string(827));
  179.     }
  180.     dliscan();
  181.     i=nrecno(sx,cp);
  182.   }
  183.  
  184.   tmp_disable_conf(0);
  185. }
  186.  
  187. int comparedl(uploadsrec *x, uploadsrec *y, int type)
  188. {
  189.   switch(type) {
  190.     case 0:
  191.       return(strcmp(x->filename,y->filename));
  192.     case 1:
  193.       if (x->daten < y->daten)
  194.         return(-1);
  195.       else
  196.         if (x->daten > y->daten)
  197.           return(1);
  198.         else
  199.           return(0);
  200.     case 2:
  201.       if (x->daten < y->daten)
  202.         return(1);
  203.       else
  204.         if (x->daten > y->daten)
  205.           return(-1);
  206.         else
  207.           return(0);
  208.   }
  209.   return(0);
  210. }
  211.  
  212.  
  213. void quicksort(int l,int r,int type)
  214. {
  215.   register int i,j,f;
  216.   uploadsrec a,a2,x;
  217.  
  218.   i=l; j=r;
  219.   f=sh_open(dlfn,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  220.   SETREC(f,((l+r)/2));
  221.   sh_read(f, (void *)&x,sizeof(uploadsrec));
  222.   do {
  223.     SETREC(f,i);
  224.     sh_read(f, (void *)&a,sizeof(uploadsrec));
  225.     while (comparedl(&a,&x,type)<0) {
  226.       SETREC(f,++i);
  227.       sh_read(f, (void *)&a,sizeof(uploadsrec));
  228.     }
  229.     SETREC(f,j);
  230.     sh_read(f, (void *)&a2,sizeof(uploadsrec));
  231.     while (comparedl(&a2,&x,type)>0) {
  232.       SETREC(f,--j);
  233.       sh_read(f, (void *)&a2,sizeof(uploadsrec));
  234.     }
  235.     if (i<=j) {
  236.       if (i!=j) {
  237.         SETREC(f,i);
  238.         sh_write(f,(void *)&a2,sizeof(uploadsrec));
  239.         SETREC(f,j);
  240.         sh_write(f,(void *)&a,sizeof(uploadsrec));
  241.       }
  242.       i++;
  243.       j--;
  244.     }
  245.   } while (i<j);
  246.   f=sh_close(f);
  247.   if (l<j)
  248.     quicksort(l,j,type);
  249.   if (i<r)
  250.     quicksort(i,r,type);
  251. }
  252.  
  253.  
  254. void sortdir(int dn, int type)
  255. {
  256.   dliscan1(dn);
  257.   if (numf>1)
  258.     quicksort(1,numf,type);
  259. }
  260.  
  261.  
  262. void sort_all(int type)
  263. {
  264.   int i;
  265.  
  266.   tmp_disable_conf(1);
  267.   for (i=0; (i<num_dirs) && (udir[i].subnum!=-1) && (!kbhitb()); i++) {
  268.     nl();
  269.     ansic(1);
  270.     outstr(get_string(828));
  271.     pl(directories[udir[i].subnum].name);
  272.     sortdir(i,type);
  273.   }
  274.   tmp_disable_conf(0);
  275. }
  276.  
  277.  
  278. void rename_file(void)
  279. {
  280.   char s[81],s1[81],s2[81],*ss,s3[81],ch;
  281.   int i,cp,f;
  282.   uploadsrec u;
  283.  
  284.   nln(2);
  285.   prt(2,get_string(829));
  286.   input(s,12);
  287.   if (s[0]==0)
  288.     return;
  289.   if (strchr(s,'.')==NULL)
  290.     strcat(s,".*");
  291.   align(s);
  292.   dliscan();
  293.   nl();
  294.   strcpy(s3,s);
  295.   i=recno(s);
  296.   while ((i>0) && (!hangup)) {
  297.     f=sh_open1(dlfn,O_RDONLY | O_BINARY);
  298.     cp=i;
  299.     SETREC(f,i);
  300.     sh_read(f,(void *)&u,sizeof(uploadsrec));
  301.     f=sh_close(f);
  302.     nl();
  303.     printfileinfo(&u,udir[curdir].subnum);
  304.     nl();
  305.     prt(5,get_string(830));
  306.     ch=ynq();
  307.     if (ch=='Q')
  308.       break;
  309.     else if (ch=='N') {
  310.       i=nrecno(s3,cp);
  311.       continue;
  312.     }
  313.     nl();
  314.     prt(2,get_string(72));
  315.     input(s,12);
  316.     if (!okfn(s))
  317.       s[0]=0;
  318.     if (s[0]) {
  319.       align(s);
  320.       if (strcmp(s,get_string(1310))) {
  321.         strcpy(s1,directories[udir[curdir].subnum].path);
  322.         strcpy(s2,s1);
  323.         strcat(s1,s);
  324.         if (exist(s1))
  325.           pl(get_string(831));
  326.         else {
  327.           strcat(s2,u.filename);
  328.           rename(s2,s1);
  329.           if (exist(s1)) {
  330.             ss=read_extended_description(u.filename);
  331.             if (ss) {
  332.               delete_extended_description(u.filename);
  333.               add_extended_description(s,ss);
  334.               bbsfree(ss);
  335.             }
  336.             strcpy(u.filename,s);
  337.           } else
  338.             pl(get_string(832));
  339.         }
  340.       }
  341.     }
  342.     nl();
  343.     pl(get_string(833));
  344.     prt(2,": ");
  345.     inputl(s,58);
  346.     if (s[0]) {
  347.       strcpy(u.description,s);
  348.     }
  349.     ss=read_extended_description(u.filename);
  350.     nln(2);
  351.     prt(5,get_string(834));
  352.     if (yn()) {
  353.       nl();
  354.       if (ss) {
  355.         prt(5,get_string(835));
  356.         if (yn()) {
  357.           bbsfree(ss);
  358.           delete_extended_description(u.filename);
  359.           u.mask &= ~mask_extended;
  360.         } else {
  361.           u.mask |= mask_extended;
  362.           modify_extended_description(&ss,
  363.             directories[udir[curdir].subnum].name,u.filename);
  364.           if (ss) {
  365.             delete_extended_description(u.filename);
  366.             add_extended_description(u.filename,ss);
  367.             bbsfree(ss);
  368.           }
  369.         }
  370.       } else {
  371.         modify_extended_description(&ss,
  372.             directories[udir[curdir].subnum].name,u.filename);
  373.         if (ss) {
  374.           add_extended_description(u.filename,ss);
  375.           bbsfree(ss);
  376.           u.mask |= mask_extended;
  377.         } else
  378.           u.mask &= ~mask_extended;
  379.       }
  380.     } else
  381.       if (ss) {
  382.         bbsfree(ss);
  383.         u.mask |= mask_extended;
  384.       } else
  385.         u.mask &= ~mask_extended;
  386.     f=sh_open(dlfn,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  387.     SETREC(f,i);
  388.     sh_write(f,(void *)&u,sizeof(uploadsrec));
  389.     f=sh_close(f);
  390.     i=nrecno(s3,cp);
  391.   }
  392. }
  393.  
  394.  
  395. int upload_file(char *fn, int dn, char *desc)
  396. {
  397.   directoryrec d;
  398.   uploadsrec u,u1;
  399.   int i,f;
  400.   char s[81],ff[81];
  401.   long l;
  402.  
  403.   d=directories[dn];
  404.   strcpy(s,fn);
  405.   align(s);
  406.   strcpy(u.filename,s);
  407.   u.ownerusr=usernum;
  408.   u.ownersys=0;
  409.   u.numdloads=0;
  410.   u.filetype=0;
  411.   u.mask=0;
  412.   if ((!(d.mask & mask_cdrom)) && (check_ul_event(dn,&u))) {
  413.     outstr(fn);
  414.     pl(get_string(836));
  415.   } else {
  416.     sprintf(ff,"%s%s",d.path,s);
  417.     f=sh_open1(ff,O_RDONLY | O_BINARY);
  418.     if (f<=0) {
  419.       if (desc && (*desc)) {
  420.         outstr(get_string(837));
  421.         outstr(fn);
  422.         outstr(": ");
  423.         pl(desc);
  424.       } else {
  425.         outstr(fn);
  426.         pl(get_string(838));
  427.       }
  428.       return(1);
  429.     }
  430.     l=filelength(f);
  431.     u.numbytes=l;
  432.     sh_close(f);
  433.     strcpy(u.upby, nam(&thisuser,usernum));
  434.     strcpy(u.date,date());
  435.     if (d.mask & mask_PD)
  436.       d.mask=mask_PD;
  437.     npr("%s: %4ldk :",u.filename,bytes_to_k(u.numbytes));
  438.     if ((desc) && (*desc)) {
  439.       strncpy(u.description,desc,58);
  440.       u.description[58]=0;
  441.       pl(u.description);
  442.     } else
  443.       inputl(u.description,58);
  444.     if (u.description[0]==0)
  445.       return(0);
  446.     get_file_idz(&u,dn);
  447.     ++thisuser.uploaded;
  448.     if (!(d.mask & mask_cdrom))
  449.       modify_database(u.filename,1);
  450.     thisuser.uk += bytes_to_k(l);
  451.     time(&l);
  452.     u.daten=l;
  453.     if (sysinfo.flags & OP_FLAGS_PACKSCAN_FREQ) {
  454.       if (!(d.mask & mask_cdrom))
  455.         remotenotify(u.filename,u.description);
  456.     }
  457.     f=sh_open(dlfn,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  458.     for (i=numf; i>=1; i--) {
  459.       SETREC(f,i);
  460.       sh_read(f,(void *)&u1,sizeof(uploadsrec));
  461.       SETREC(f,i+1);
  462.       sh_write(f,(void *)&u1,sizeof(uploadsrec));
  463.     }
  464.     SETREC(f,1);
  465.     sh_write(f,(void *)&u,sizeof(uploadsrec));
  466.     ++numf;
  467.     SETREC(f,0);
  468.     sh_read(f, &u1, sizeof(uploadsrec));
  469.     u1.numbytes=numf;
  470.     u1.daten=l;
  471.     dir_dates[dn]=l;
  472.     SETREC(f,0);
  473.     sh_write(f,(void *)&u1,sizeof(uploadsrec));
  474.     f=sh_close(f);
  475.     lock_status();
  476.     ++status.uptoday;
  477.     ++status.filechange[filechange_upload];
  478.     save_status();
  479.     sprintf(s,get_stringx(1,42),u.filename,d.name);
  480.     sysoplog(s);
  481.     topscreen();
  482.   }
  483.   return(1);
  484. }
  485.  
  486.  
  487. int maybe_upload(char *fn, int dn, char *desc)
  488. {
  489.   char s[81], ch, s1[81];
  490.   int i,i1=0,ok=1,ocd,f;
  491.   uploadsrec u;
  492.  
  493.   strcpy(s,fn);
  494.   align(s);
  495.   i=recno(s);
  496.  
  497.   if (i==-1) {
  498.     if ((sysinfo.flags & OP_FLAGS_FAST_SEARCH) &&
  499.         ((!is_uploadable(fn)) && (dcs()))) {
  500.       npr("2%-12s: ", fn);
  501.       prt(5,get_string(1322));
  502.       ch=ynq();
  503.       if (ch==*str_quit)
  504.         return(0);
  505.       else {
  506.         if (ch==*str_no) {
  507.           prt(5,get_string(835));
  508.           if (yn()) {
  509.             sprintf(s1,"%s%s", directories[dn].path, fn);
  510.             unlink(s1);
  511.             nl();
  512.             return(1);
  513.           } else {
  514.             return(1);
  515.           }
  516.         }
  517.       }
  518.     }
  519.     if (!upload_file(s,udir[dn].subnum,desc))
  520.       ok=0;
  521.   } else {
  522.     f=sh_open1(dlfn,O_RDONLY | O_BINARY);
  523.     SETREC(f,i);
  524.     sh_read(f,(void *)&u, sizeof(uploadsrec));
  525.     f=sh_close(f);
  526.     ocd=curdir;
  527.     curdir=dn;
  528.     printinfo(&u,&i1);
  529.     curdir=ocd;
  530.     if (i1)
  531.       ok=0;
  532.   }
  533.   return(ok);
  534. }
  535.  
  536. void upload_files(char *fn, int dn, int type)
  537. /* This assumes the file holds listings of files, one per line, to be
  538.  * uploaded.  The first word (delimited by space/tab) must be the filename.
  539.  * after the filename are optional tab/space separated words (such as file
  540.  * size or date/time).  After the optional words is the description, which
  541.  * is from that position to the end of the line.  the "type" parameter gives
  542.  * the number of optional words between the filename and description.
  543.  * the optional words (size, date/time) are ignored completely.
  544.  */
  545. {
  546.   char s[255],*fn1,*desc,last_fn[81],*ext=NULL;
  547.   FILE *f;
  548.   int ok=1,abort=0,next=0,ok1,i,f1;
  549.   uploadsrec u;
  550.  
  551.   last_fn[0]=0;
  552.   dliscan1(udir[dn].subnum);
  553.  
  554.   f=fsh_open(fn,"r");
  555.   if (!f) {
  556.     sprintf(s,"%s%s",directories[udir[dn].subnum].path,fn);
  557.     f=fsh_open(s,"r");
  558.   }
  559.   if (!f) {
  560.     outstr(fn);
  561.     pl(get_string(1528));
  562.   } else {
  563.     while (ok && fgets(s,250,f)) {
  564.       if (s[0]<32)
  565.         continue;
  566.       else if (s[0]==32) {
  567.         if (last_fn[0]) {
  568.           if (!ext) {
  569.             ext=malloca(4096L);
  570.             *ext=0;
  571.           }
  572.           for (desc=s; (*desc==' ') || (*desc=='\t'); desc++)
  573.             ;
  574.           if (*desc=='|') {
  575.             do {
  576.               desc++;
  577.             } while ((*desc==' ') || (*desc=='\t'));
  578.             fn1=strchr(desc,'\n');
  579.             if (fn1)
  580.               *fn1=0;
  581.             strcat(ext, desc);
  582.             strcat(ext,"\r\n");
  583.           }
  584.         }
  585.       } else {
  586.         ok1=0;
  587.         fn1=strtok(s," \t\n");
  588.         if (fn1) {
  589.           ok1=1;
  590.           for (i=0; ok1 && (i<type); i++)
  591.             if (strtok(NULL," \t\n")==NULL)
  592.               ok1=0;
  593.           if (ok1) {
  594.             desc=strtok(NULL,"\n");
  595.             if (!desc)
  596.               ok1=0;
  597.           }
  598.         }
  599.         if (ok1) {
  600.           if (last_fn[0] && ext && *ext) {
  601.             f1=sh_open(dlfn,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  602.             SETREC(f1,1);
  603.             sh_read(f1,(void *)&u, sizeof(uploadsrec));
  604.             if (strcmp(last_fn,u.filename)==0) {
  605.               modify_database(u.filename,1);
  606.               add_extended_description(last_fn, ext);
  607.               u.mask |= mask_extended;
  608.               SETREC(f1,1);
  609.               sh_write(f1, (void *)&u, sizeof(uploadsrec));
  610.             }
  611.             f1=sh_close(f1);
  612.             *ext=0;
  613.           }
  614.           while ((*desc==' ') || (*desc=='\t'))
  615.             ++desc;
  616.           ok=maybe_upload(fn1,dn,desc);
  617.           checka(&abort,&next);
  618.           if (abort)
  619.             ok=0;
  620.           if (ok) {
  621.             strcpy(last_fn, fn1);
  622.             align(last_fn);
  623.             if (ext)
  624.               *ext=0;
  625.           }
  626.         }
  627.       }
  628.     }
  629.     fsh_close(f);
  630.     if (ok && last_fn[0] && ext && *ext) {
  631.       f1=sh_open(dlfn,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  632.       SETREC(f1,1);
  633.       sh_read(f1,(void *)&u, sizeof(uploadsrec));
  634.       if (strcmp(last_fn,u.filename)==0) {
  635.         modify_database(u.filename,1);
  636.         add_extended_description(last_fn, ext);
  637.         u.mask |= mask_extended;
  638.         SETREC(f1,1);
  639.         sh_write(f1, (void *)&u, sizeof(uploadsrec));
  640.       }
  641.       f1=sh_close(f1);
  642.     }
  643.   }
  644.  
  645.   if (ext)
  646.     bbsfree(ext);
  647. }
  648.  
  649. int uploadall(int dn)
  650. {
  651.   int i1,f1,maxf,ok,abort=0,next;
  652.   char s[81],s1[81];
  653.   struct ffblk ff;
  654.  
  655.   dliscan1(udir[dn].subnum);
  656.   nln(2);
  657.   strcpy(s,"*.*");
  658.   strcpy(s1,(directories[udir[dn].subnum].path));
  659.   maxf=directories[udir[dn].subnum].maxfiles;
  660.   strcat(s1,s);
  661.   f1=findfirst(s1,&ff,0);
  662.   ok=1;
  663.   i1=0;
  664.   while ((f1==0) && (!hangup) && (numf<maxf) && (ok) && (!i1) && (!abort)) {
  665.     ok=maybe_upload(ff.ff_name,dn,NULL);
  666.     f1=findnext(&ff);
  667.     checka(&abort,&next);
  668.   }
  669.   if ((!ok) || (abort))
  670.     pl(get_string(14));
  671.   if (numf>=maxf)
  672.     pl(get_string(839));
  673.   return(i1);
  674. }
  675.  
  676.  
  677. void relist(void)
  678. {
  679.   char s[85],s1[40],s2[81];
  680.   int i,i1,next,abort=0,fc;
  681.   int tcd=-1, otag;
  682.  
  683.   if (!filelist)
  684.     return;
  685.   outchr(12);
  686.   lines_listed=0;
  687.   otag=tagging;
  688.   tagging=0;
  689.   fc=thisuser.sysstatus & sysstatus_extra_color;
  690.   if (sysinfo.flags & OP_FLAGS_FAST_TAG_RELIST) {
  691.     ansic(fc ? FRAME : 0);
  692.     if (okansi())
  693.       pl(get_string(1354));
  694.     else
  695.       pl(get_string(1355));
  696.   }
  697.   for (i=0;i<tagptr;i++) {
  698.     if (!(sysinfo.flags & OP_FLAGS_FAST_TAG_RELIST)) {
  699.       if (tcd!=filelist[i].directory) {
  700.         ansic(fc ? FRAME : 0);
  701.         if (tcd!=-1) {
  702.           if (okansi())
  703.             npr("\r%s\r\n",get_string(1356));
  704.           else
  705.             npr("\r%s\r\n",get_string(1357));
  706.         }
  707.         tcd=filelist[i].directory;
  708.         if (fc)
  709.           ansic(2);
  710.         npr("%s - #%s.\r\n",directories[tcd].name,udir[tcd].keys);
  711.         ansic(fc ? FRAME : 0);
  712.         if (okansi())
  713.           npr("%s\r\n",get_string(1317));
  714.         else
  715.           npr("%s\r\n",get_string(1318));
  716.       }
  717.     }
  718.     sprintf(s,"%d%2d%d%c",
  719.       check_batch_queue(filelist[i].u.filename) ? 6 : 0,
  720.       i+1, fc ? FRAME : 0, okansi() ? '║' : '|' );
  721.     osan(s,&abort,&next);
  722.     if (fc)
  723.       ansic(1);
  724.     strncpy(s,filelist[i].u.filename,8);
  725.     s[8]=0;
  726.     osan(s,&abort,&next);
  727.     strncpy(s,&((filelist[i].u.filename)[8]),4);
  728.     s[4]=0;
  729.     if (fc)
  730.       ansic(1);
  731.     osan(s,&abort,&next);
  732.     ansic(fc ? FRAME : 0);
  733.     osan((okansi() ? "║" : ":"),&abort,&next);
  734.  
  735.     ltoa(bytes_to_k(filelist[i].u.numbytes),s1,10);
  736.     strcat(s1,"k");
  737.     if (!(sysinfo.flags & OP_FLAGS_FAST_TAG_RELIST)) {
  738.       if (!(directories[tcd].mask & mask_cdrom)) {
  739.         strcpy(s2,directories[tcd].path);
  740.         strcat(s2,filelist[i].u.filename);
  741.         if (!exist(s2))
  742.           strcpy(s1,get_string(741));
  743.       }
  744.     }
  745.     for (i1=0; i1<5-(int)strlen(s1); i1++)
  746.       s[i1]=32;
  747.     s[i1]=0;
  748.     strcat(s,s1);
  749.     if (fc)
  750.       ansic(2);
  751.     osan(s,&abort,&next);
  752.  
  753.     ansic(fc ? FRAME : 0);
  754.     osan((okansi() ? "║" : "|"),&abort,&next);
  755.     sprintf(s1,"%d",filelist[i].u.numdloads);
  756.  
  757.     for (i1=0; i1<4-strlen(s1); i1++)
  758.       s[i1]=32;
  759.     s[i1]=0;
  760.     strcat(s,s1);
  761.     if (fc)
  762.       ansic(2);
  763.     osan(s,&abort,&next);
  764.  
  765.     ansic(fc ? FRAME : 0);
  766.     osan((okansi() ? "║" : "|"),&abort,&next);
  767.     sprintf(s,"%d%s",
  768.       (filelist[i].u.mask & mask_extended) ? 1 : 2,
  769.       filelist[i].u.description);
  770.     plal(s,thisuser.screenchars-28,&abort);
  771.   }
  772.   ansic(fc ? FRAME : 0);
  773.   if (okansi())
  774.     npr("\r%s\r\n",get_string(1356));
  775.   else
  776.     npr("\r%s\r\n",get_string(1357));
  777.   tagging=otag;
  778.   lines_listed=0;
  779. }
  780.  
  781. /****************************************************************************/
  782.  
  783. void edit_database(void)
  784. /*
  785.  * Allows user to add or remove ALLOW.DAT entries.
  786.  */
  787. {
  788.   unsigned char ch,s[20];
  789.   int done=0;
  790.  
  791.   if (!(sysinfo.flags & OP_FLAGS_FAST_SEARCH))
  792.     return;
  793.  
  794.   do {
  795.     nl();
  796.     pl(get_string(1382));
  797.     pl(get_string(1383));
  798.     pl(get_string(1384));
  799.     nl();
  800.     prt(1,get_string(1385));
  801.     ch=onek("QAR");
  802.     switch (ch) {
  803.       case 'A':
  804.         nl();
  805.         prt(2,get_string(44));
  806.         mpl(12);
  807.         input(s,12);
  808.         if (s[0])
  809.           modify_database(s,1);
  810.         break;
  811.       case 'R':
  812.         nl();
  813.         prt(2,get_string(44));
  814.         mpl(12);
  815.         input(s,12);
  816.         if (s[0])
  817.           modify_database(s,0);
  818.         break;
  819.       case 'Q':
  820.         done=1;
  821.         break;
  822.     }
  823.   } while ((!hangup) && (!done));
  824. }
  825.  
  826.  
  827. /****************************************************************************/
  828. /*
  829.  * Checks the database file to see if filename is there.  If so, the record
  830.  * number plus one is returned.  If not, the negative of record number
  831.  * that it would be minus one is returned.  The plus one is there so that there
  832.  * is no record #0 ambiguity.
  833.  */
  834.  
  835. long db_index(int af, char *fn)
  836. {
  837.   char cfn[18],tfn[81], tfn1[81];
  838.   int i;
  839.   long hirec, lorec, currec, ocurrec=-1;
  840.  
  841.   strcpy(tfn1, fn);
  842.   align(tfn1);
  843.   strcpy(tfn,stripfn(tfn1));
  844.  
  845.   hirec=filelength(af)/13;
  846.   lorec=0;
  847.  
  848.   if (hirec==0)
  849.     return(-1);
  850.  
  851.   while (1) {
  852.     currec=((long)((hirec+lorec)/2));
  853.     if (currec==ocurrec) {
  854.       if (i<0)
  855.         return(-(currec+2));
  856.       else
  857.         return(-(currec+1));
  858.     }
  859.     ocurrec=currec;
  860.     sh_lseek(af,((long) (currec*13)),SEEK_SET);
  861.     sh_read(af,(void *)&cfn,13);
  862.     i=strcmp(cfn,tfn);
  863.  
  864.     /* found */
  865.     if (i==0) {
  866.       return(currec+1);
  867.     } else {
  868.       if (i<0) {
  869.         lorec=currec;
  870.       } else {
  871.         hirec=currec;
  872.       }
  873.     }
  874.   }
  875. }
  876.  
  877. /****************************************************************************/
  878. /*
  879.  * Adds or deletes a single entry to/from filename database.
  880.  */
  881.  
  882. #define ALLOW_BUFSIZE 61440
  883.  
  884. void modify_database(char *fn, int add)
  885. {
  886.   char dbfn[81], tfn[81], tfn1[81];
  887.   int af;
  888.   unsigned int nb;
  889.   long rec, len, l, l1,cp;
  890.   char *bfr;
  891.  
  892.   if (!(sysinfo.flags & OP_FLAGS_FAST_SEARCH))
  893.     return;
  894.  
  895.   sprintf(dbfn, "%sALLOW.DAT", syscfg.datadir);
  896.   af=sh_open1(dbfn, O_RDWR|O_BINARY|O_CREAT);
  897.  
  898.   if (af<0)
  899.     return;
  900.  
  901.   rec=db_index(af, fn);
  902.  
  903.   if (((rec<0) && (!add)) || ((rec>0) && (add))) {
  904.     sh_close(af);
  905.     return;
  906.   }
  907.  
  908.   bfr=(char *)malloca(ALLOW_BUFSIZE);
  909.   if (!bfr) {
  910.     sh_close(af);
  911.     return;
  912.   }
  913.  
  914.   len=filelength(af);
  915.  
  916.   if (add) {
  917.     cp=(-1-rec)*13;
  918.     l1=len;
  919.  
  920.     do {
  921.       l=l1-cp;
  922.       if (l<ALLOW_BUFSIZE)
  923.         nb=(unsigned int)l;
  924.       else
  925.         nb=ALLOW_BUFSIZE;
  926.       if (nb) {
  927.         sh_lseek(af, l1-(long)nb, SEEK_SET);
  928.         sh_read(af, bfr, nb);
  929.         sh_lseek(af, l1-(long)nb + 13, SEEK_SET);
  930.         sh_write(af, bfr, nb);
  931.         l1 -= nb;
  932.       }
  933.     } while (nb==ALLOW_BUFSIZE);
  934.  
  935.     /* put in the new value */
  936.     strcpy(tfn1, fn);
  937.     align(tfn1);
  938.     strncpy(tfn,stripfn(tfn1), 13);
  939.     sh_lseek(af, cp, SEEK_SET);
  940.     sh_write(af,(void *)tfn,13);
  941.   } else {
  942.     cp=rec*13;
  943.  
  944.     do {
  945.       l=len-cp;
  946.       if (l<ALLOW_BUFSIZE)
  947.         nb=(unsigned int)l;
  948.       else
  949.         nb=ALLOW_BUFSIZE;
  950.       if (nb) {
  951.         sh_lseek(af, cp, SEEK_SET);
  952.         sh_read(af, bfr, nb);
  953.         sh_lseek(af, cp-13, SEEK_SET);
  954.         sh_write(af, bfr, nb);
  955.         cp += nb;
  956.       }
  957.     } while (nb==ALLOW_BUFSIZE);
  958.  
  959.     /* truncate the file */
  960.     chsize(af, len-13);
  961.   }
  962.  
  963.   bbsfree(bfr);
  964.   sh_close(af);
  965. }
  966.  
  967. /****************************************************************************/
  968. /*
  969.  * Returns 1 if file not found in filename database.
  970.  */
  971.  
  972. int is_uploadable(char *fn)
  973. {
  974.   char dbfn[81];
  975.   int af;
  976.   long rc;
  977.  
  978.   if (!(sysinfo.flags & OP_FLAGS_FAST_SEARCH))
  979.     return(1);;
  980.  
  981.   sprintf(dbfn, "%sALLOW.DAT", syscfg.datadir);
  982.   af=sh_open1(dbfn, O_RDONLY|O_BINARY);
  983.   if (af<0)
  984.     return(1);
  985.   rc=db_index(af, fn);
  986.   sh_close(af);
  987.   if (rc<0)
  988.     return(1);
  989.   else
  990.     return(0);
  991. }
  992. /****************************************************************************/
  993.  
  994.  
  995. void l_config_nscan(void)
  996. {
  997.   int i,abort,i1;
  998.   char s[81], s2[81];
  999.  
  1000.   abort=0;
  1001.   nl();
  1002.   pl(get_string(802));
  1003.   nl();
  1004.   for (i=0; (i<num_dirs) && (udir[i].subnum!=-1) && (!abort); i++) {
  1005.     i1=udir[i].subnum;
  1006.     if (qsc_n[i1/32]&(1L<<(i1%32)))
  1007.       strcpy(s,"* ");
  1008.     else
  1009.       strcpy(s,"  ");
  1010.     sprintf(s2,"%s%s. %s",s,udir[i].keys, directories[i1].name);
  1011.     pla(s2,&abort);
  1012.   }
  1013.   nln(2);
  1014. }
  1015.  
  1016. void config_nscan(void)
  1017. {
  1018.   char *s,s1[MAX_CONFERENCES+2],s2[120],ch;
  1019.   int i,i1,done,done1,oc,os,abort=0;
  1020.  
  1021.   done=done1=0;
  1022.   oc=curconfdir;
  1023.   os=udir[curdir].subnum;
  1024.  
  1025.   do {
  1026.     if ((okconf(&thisuser)) && (uconfdir[1].confnum!=-1)) {
  1027.       abort=0;
  1028.       strcpy(s1," ");
  1029.       nl();
  1030.       pl(get_string(1358));
  1031.       nl();
  1032.       i=0;
  1033.       while ((i<dirconfnum) && (uconfdir[i].confnum!=-1) && (!abort)) {
  1034.         sprintf(s2,"%c) %s",dirconfs[uconfdir[i].confnum].designator,
  1035.           stripcolors(dirconfs[uconfdir[i].confnum].name));
  1036.         pla(s2,&abort);
  1037.         s1[i+1]=dirconfs[uconfdir[i].confnum].designator;
  1038.         s1[i+2]=0;
  1039.         i++;
  1040.       }
  1041.       nl();
  1042.       outstr(get_string(1082));
  1043.       outstr(&s1[1]);
  1044.       outstr(get_string(1083));
  1045.       ch=onek(s1);
  1046.     } else
  1047.       ch='-';
  1048.     switch (ch) {
  1049.       case ' ':
  1050.         done1=1;
  1051.         break;
  1052.       default:
  1053.         if ((okconf(&thisuser)) && (dirconfnum>1)) {
  1054.           i=0;
  1055.           while ((ch!=dirconfs[uconfdir[i].confnum].designator) && (i<dirconfnum))
  1056.             i++;
  1057.           if (i>=dirconfnum)
  1058.             break;
  1059.  
  1060.           setuconf(CONF_DIRS, i, -1);
  1061.         }
  1062.  
  1063.         l_config_nscan();
  1064.         done=0;
  1065.         do {
  1066.           nl();
  1067.           outstr(get_string(1359));
  1068.           s=mmkey(1);
  1069.           if (s[0]) {
  1070.             for (i=0; i<num_dirs; i++) {
  1071.               i1=udir[i].subnum;
  1072.               if (strcmp(udir[i].keys,s)==0) {
  1073.                 qsc_n[i1/32] ^= 1L<<(i1%32);
  1074.               }
  1075.               if (strcmp(s,"S")==0) {
  1076.                 qsc_n[i1/32] |= 1L<<(i1%32);
  1077.               }
  1078.               if (strcmp(s,"C")==0) {
  1079.                 qsc_n[i1/32] &= ~(1L<<(i1%32));
  1080.               }
  1081.             }
  1082.             if (strcmp(s,"Q")==0)
  1083.               done=1;
  1084.             if (strcmp(s,"?")==0)
  1085.               l_config_nscan();
  1086.           }
  1087.         } while ((!done) && (!hangup));
  1088.         break;
  1089.     }
  1090.     if ((!okconf(&thisuser)) || (uconfdir[1].confnum==-1))
  1091.       done1=1;
  1092.   } while ((!done1) && (!hangup));
  1093.  
  1094.   if (okconf(&thisuser))
  1095.     setuconf(CONF_DIRS, oc, os);
  1096. }
  1097.  
  1098.  
  1099. void xfer_defaults(void)
  1100. {
  1101.   char s[81],ch;
  1102.   int i,done;
  1103.  
  1104.   done=0;
  1105.   do {
  1106.     if (menu_on()) {
  1107.       printmenu(318);
  1108.       if ((thisuser.sysstatus & sysstatus_no_tag) == 0)
  1109.             comstr("|@7O3BX\r ");
  1110.       if (thisuser.sysstatus & sysstatus_nscan_file_system)
  1111.             comstr("|@7O4XX\r ");
  1112.     } else {
  1113.       outchr(12);
  1114.       pl(get_string(804));
  1115.       pl(get_string(805));
  1116.       outstr(get_string(806));
  1117.       npr(" (%s).\r\n", thisuser.sysstatus & sysstatus_nscan_file_system?str_yes:str_no);
  1118.       outstr(get_string(807));
  1119.       npr(" (%d %s%s).\r\n", thisuser.num_extended, get_string(808),
  1120.           thisuser.num_extended==1?"":"s");
  1121.       outstr(get_string(1360));
  1122.       if (thisuser.sysstatus & sysstatus_no_tag)
  1123.         outstr(get_string(1361));
  1124.       else
  1125.         outstr(get_string(1362));
  1126.       pl(")");
  1127.       pl(get_string(809));
  1128.       nl();
  1129.       prt(2,get_string(297));
  1130.     }
  1131.     helpl=32;
  1132.     ch=onek("Q12345");
  1133.     if (menu_on() && ch != '3' && ch != '5') {
  1134.       printmenu(319);
  1135.     }
  1136.     switch(ch) {
  1137.       case 'Q':
  1138.         done=1;
  1139.         break;
  1140.       case '1':
  1141.         helpl=24;
  1142.         config_nscan();
  1143.         break;
  1144.       case '2':
  1145.         nln(2);
  1146.         pl(get_string(810));
  1147.         nl();
  1148.         helpl=40;
  1149.         i=get_protocol(xf_down);
  1150.         if (i>=0)
  1151.           thisuser.defprot=i;
  1152.         break;
  1153.       case '3':
  1154.         thisuser.sysstatus ^= sysstatus_nscan_file_system;
  1155.         break;
  1156.       case '4':
  1157.         nln(2);
  1158.         pl(get_string(813));
  1159.         sprintf(s,"%s%d7)",get_string(814),sysinfo.max_extend_lines);
  1160.         pl(s);
  1161.         outstr(get_string(815));
  1162.         pln(thisuser.num_extended);
  1163.         prt(5,"? ");
  1164.         helpl=41;
  1165.         input(s,3);
  1166.         if (s[0]) {
  1167.           i=atoi(s);
  1168.           if ((i>=0) && (i<=sysinfo.max_extend_lines))
  1169.             thisuser.num_extended=i;
  1170.         }
  1171.         break;
  1172.       case '5':
  1173.           thisuser.sysstatus ^= sysstatus_no_tag;
  1174.         break;
  1175.     }
  1176.   } while ((!done) && (!hangup));
  1177. }
  1178.  
  1179.  
  1180.  
  1181. void finddescription(void)
  1182. {
  1183.   uploadsrec u;
  1184.   int i,i1,i2,abort,ocd,pts,next=0,f,count,color,ac=0;
  1185.   char s[81],s1[81];
  1186.  
  1187.   nl();
  1188.   if ((uconfdir[1].confnum!=-1) && (okconf(&thisuser))) {
  1189.     if (!x_only) {
  1190.       prt(5,get_string(1379));
  1191.       ac=yn();
  1192.     } else
  1193.       ac=1;
  1194.     if (ac)
  1195.       tmp_disable_conf(1);
  1196.   }
  1197.   nl();
  1198.   pl(get_string(793));
  1199.   nl();
  1200.   pl(get_string(794));
  1201.   outstr(":");
  1202.   input(s1,58);
  1203.   if (s1[0]==0) {
  1204.     tmp_disable_conf(0);
  1205.     return;
  1206.   }
  1207.  
  1208.   ocd=curdir;
  1209.   abort=0;
  1210.   num_listed=0;
  1211.   count=0;
  1212.   color=3;
  1213.   if (!x_only) {
  1214.     outstr("\r");
  1215.     outstr(get_string(1184));
  1216.   }
  1217.   lines_listed=0;
  1218.   for (i=0; (i<num_dirs) && (!abort) && (!hangup) && (tagging!=0)
  1219.     && (udir[i].subnum!=-1); i++) {
  1220.     i1=udir[i].subnum;
  1221.     pts=0;
  1222.     titled=1;
  1223.     if (qsc_n[i1/32]&(1L<<(i1%32)))
  1224.       pts=1;
  1225.     pts=1;
  1226.     /* remove pts=1 to search only marked directories */
  1227.     if ((pts) && (!abort) && (tagging!=0)) {
  1228.       if (!x_only) {
  1229.         count++;
  1230.         npr("%d.",color);
  1231.         if (count==DOTS) {
  1232.           outstr("\r");
  1233.           outstr(get_string(1184));
  1234.           color++;
  1235.           count=0;
  1236.           if (color==4)
  1237.             color++;
  1238.           if (color==10)
  1239.             color=0;
  1240.         }
  1241.       }
  1242.       curdir=i;
  1243.       dliscan();
  1244.       f=sh_open1(dlfn,O_RDONLY | O_BINARY);
  1245.       for (i1=1; (i1<=numf) && (!abort) && (!hangup) && (tagging !=0); i1++) {
  1246.         SETREC(f,i1);
  1247.         sh_read(f,(void *)&u,sizeof(uploadsrec));
  1248.         strcpy(s,u.description);
  1249.         for (i2=0; i2<strlen(s); i2++)
  1250.           s[i2]=upcase(s[i2]);
  1251.         if (strstr(s,s1)!=NULL) {
  1252.           f=sh_close(f);
  1253.           printinfo(&u, &abort);
  1254.           f=sh_open1(dlfn,O_RDONLY | O_BINARY);
  1255.         } else if (!empty())
  1256.           checka(&abort,&next);
  1257.       }
  1258.       f=sh_close(f);
  1259.     }
  1260.   }
  1261.   if (ac)
  1262.     tmp_disable_conf(0);
  1263.   curdir=ocd;
  1264.   endlist(1);
  1265. }
  1266.  
  1267.  
  1268. void arc_l(void)
  1269. {
  1270.   char s[81];
  1271.   int i,abort,next,i1,f;
  1272.   uploadsrec u;
  1273.  
  1274.   nl();
  1275.   prt(2,get_string(795));
  1276.   input(s,12);
  1277.   if (strchr(s,'.')==NULL)
  1278.     strcat(s,".*");
  1279.   if (!okfn(s))
  1280.     s[0]=0;
  1281.   align(s);
  1282.   dliscan();
  1283.   abort=0;
  1284.   next=0;
  1285.   i=recno(s);
  1286.   do {
  1287.     if (i>0) {
  1288.       f=sh_open1(dlfn,O_RDONLY | O_BINARY);
  1289.       SETREC(f,i);
  1290.       sh_read(f,(void *)&u,sizeof(uploadsrec));
  1291.       f=sh_close(f);
  1292.       i1=list_arc_out(stripfn(u.filename),directories[udir[curdir].subnum].path);
  1293.       if (i1)
  1294.         abort=1;
  1295.       checka(&abort,&next);
  1296.       i=nrecno(s,i);
  1297.     }
  1298.   } while ((i>0) && (!hangup) && (!abort));
  1299. }
  1300.  
  1301.  
  1302.