home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / W / WWIVSOR.ZIP / BATCH.C next >
Text File  |  1995-05-12  |  23KB  |  962 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. #include "vars.h"
  16.  
  17. #pragma hdrstop
  18.  
  19. #include <dir.h>
  20.  
  21. #define SETREC(f,i)  sh_lseek(f,((long) (i))*((long)sizeof(uploadsrec)),SEEK_SET);
  22.  
  23. /****************************************************************************/
  24.  
  25. /*
  26.  * Shows listing of files currently in batch queue(s), both upload and
  27.  * download. Shows estimated time, by item, for files in the d/l queue.
  28.  */
  29.  
  30. void listbatch(void)
  31. {
  32.   char s[81];
  33.   int abort,i;
  34.  
  35.   abort=0;
  36.   nl();
  37.   outstr(get_string(864));
  38.   npr("%d  ",numbatch);
  39.   if (numbatchdl) {
  40.     outstr(get_string(865));
  41.     pl(ctim(batchtime));
  42.   } else
  43.     nl();
  44.   nl();
  45.   for (i=0; (i<numbatch) && (!abort) && (!hangup); i++) {
  46.     if (batch[i].sending)
  47.       sprintf(s,"%d. %s %s   %s  %s",
  48.       i+1,
  49.       get_string(1621),
  50.       batch[i].filename,
  51.       ctim(batch[i].time),
  52.       directories[batch[i].dir].name);
  53.     else
  54.       sprintf(s,"%d. %s %s             %s",
  55.       i+1,
  56.       get_string(1622),
  57.       batch[i].filename,
  58.       directories[batch[i].dir].name);
  59.  
  60.     pla(s,&abort);
  61.   }
  62. }
  63.  
  64. /****************************************************************************/
  65.  
  66. /*
  67.  * Deletes one item (index i) from the d/l batch queue.
  68.  */
  69.  
  70. void delbatch(int i)
  71. {
  72.   int i1;
  73.  
  74.   if (i<numbatch) {
  75.     if (batch[i].sending) {
  76.       batchtime -= batch[i].time;
  77.       --numbatchdl;
  78.     }
  79.     --numbatch;
  80.     for (i1=i; i1<=numbatch; i1++) {
  81.       batch[i1]=batch[i1+1];
  82.     }
  83.   }
  84. }
  85.  
  86. /****************************************************************************/
  87.  
  88. void downloaded(char *fn, long cps)
  89. {
  90.   int i,i1,f;
  91.   uploadsrec u;
  92.   char s[161];
  93.   userrec ur;
  94.  
  95.   for (i1=0; i1<numbatch; i1++) {
  96.     if ((strcmp(fn,batch[i1].filename)==0) && (batch[i1].sending)) {
  97.       dliscan1(batch[i1].dir);
  98.       i=recno((batch[i1].filename));
  99.       if (i>0) {
  100.         f=sh_open(dlfn,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  101.         SETREC(f,i);
  102.         sh_read(f,(void *)&u,sizeof(uploadsrec));
  103.         ++thisuser.downloaded;
  104.         thisuser.dk += (int) (bytes_to_k(u.numbytes));
  105.         ++u.numdloads;
  106.         SETREC(f,i);
  107.         sh_write(f,(void *)&u,sizeof(uploadsrec));
  108.         f=sh_close(f);
  109.         if (cps)
  110.           sprintf(s,get_stringx(1,50),u.filename, cps);
  111.         else
  112.           sprintf(s,get_stringx(1,43),u.filename);
  113.         sysoplog(s);
  114.         if (syscfg.sysconfig & sysconfig_log_dl) {
  115.           read_user(u.ownerusr, &ur);
  116.           if (!(ur.inact & inact_deleted)) {
  117.             if (date_to_daten(ur.firston) < u.daten) {
  118.               sprintf(s,get_stringx(1,51),
  119.                 nam(&thisuser,usernum), u.filename, date());
  120.               ssm(u.ownerusr,0,s);
  121.             }
  122.           }
  123.         }
  124.       }
  125.       delbatch(i1);
  126.  
  127.       return;
  128.     }
  129.   }
  130.   sprintf(s,get_stringx(1,52),fn);
  131.   sysoplog(s);
  132. }
  133.  
  134. /****************************************************************************/
  135.  
  136. void didnt_upload(int ind)
  137. {
  138.   int i,i1,f;
  139.   char s[161];
  140.   uploadsrec u;
  141.  
  142.   if (batch[ind].sending)
  143.     return;
  144.  
  145.   dliscan1(batch[ind].dir);
  146.   i=recno(batch[ind].filename);
  147.   if (i>0) {
  148.     f=sh_open(dlfn,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  149.     do {
  150.       SETREC(f,i);
  151.       sh_read(f, &u, sizeof(uploadsrec));
  152.       if (u.numbytes!=0) {
  153.         f=sh_close(f);
  154.         i=nrecno(batch[ind].filename, i);
  155.         f=sh_open(dlfn,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  156.       }
  157.     } while ((i!=-1) && (u.numbytes!=0));
  158.     if ((i!=-1) && (u.numbytes==0)) {
  159.       if (u.mask & mask_extended)
  160.         delete_extended_description(u.filename);
  161.       for (i1=i; i1<numf; i1++) {
  162.         SETREC(f,i1+1);
  163.         sh_read(f,(void *)&u,sizeof(uploadsrec));
  164.         SETREC(f,i1);
  165.         sh_write(f,(void *)&u,sizeof(uploadsrec));
  166.       }
  167.       --i;
  168.       --numf;
  169.       SETREC(f,0);
  170.       sh_read(f, &u, sizeof(uploadsrec));
  171.       u.numbytes=numf;
  172.       SETREC(f,0);
  173.       sh_write(f,(void *)&u,sizeof(uploadsrec));
  174.       f=sh_close(f);
  175.       return;
  176.     }
  177.     f=sh_close(f);
  178.   }
  179.   sprintf(s,get_stringx(1,53),batch[ind].filename);
  180.   sysoplog(s);
  181. }
  182.  
  183. /****************************************************************************/
  184.  
  185. int try_to_ul(char *fn)
  186. {
  187.  
  188.   if (hangup)
  189.     return(1);
  190.  
  191.   if (!okfn(fn))
  192.     return(1);
  193.  
  194.   /* future expansion here */
  195.  
  196.   /* yes, this should be return(1) until there is code above to prompt the */
  197.   /* user for the file's info, and to handle uploading it */
  198.   return(1);
  199. }
  200.  
  201. /****************************************************************************/
  202.  
  203. void uploaded(char *fn, long cps)
  204. {
  205.   int i1, rn, f, f1;
  206.   uploadsrec u;
  207.   char s[161], s1[81], s2[81];
  208.  
  209.   for (i1=0; i1<numbatch; i1++) {
  210.     if ((strcmp(fn,batch[i1].filename)==0) && (!batch[i1].sending)) {
  211.       dliscan1(batch[i1].dir);
  212.       rn=recno((batch[i1].filename));
  213.       if (rn>0) {
  214.         f=sh_open(dlfn,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  215.         do {
  216.           SETREC(f,rn);
  217.           sh_read(f, &u, sizeof(uploadsrec));
  218.           if (u.numbytes!=0)
  219.             rn=nrecno(batch[i1].filename, rn);
  220.         } while ((rn!=-1) && (u.numbytes!=0));
  221.         f=sh_close(f);
  222.         if ((rn!=-1) && (u.numbytes==0)) {
  223.  
  224.           sprintf(s1,"%s%s",syscfgovr.batchdir, fn);
  225.           sprintf(s2,"%s%s", directories[batch[i1].dir].path, fn);
  226.  
  227.           if ((strcmp(s1,s2)!=0) && (exist(s1))) {
  228.             f1=0;
  229.             if ((s1[1]!=':') && (s2[1]!=':'))
  230.               f1=1;
  231.             if ((s1[1]==':') && (s2[1]==':') && (s1[0]==s2[0]))
  232.               f1=1;
  233.             if (f1) {
  234.               rename(s1,s2);
  235.               unlink(s1);
  236.             } else {
  237.               copy_file(s1,s2);
  238.               unlink(s1);
  239.             }
  240.           }
  241.  
  242.           f1=sh_open1(s2,O_RDONLY | O_BINARY);
  243.           if (f1>0) {
  244.             if (syscfg.upload_c[0]) {
  245.               sh_close(f1);
  246.               if (check_ul_event(batch[i1].dir, &u)) {
  247.                 didnt_upload(i1);
  248.                 f1=-1;
  249.               } else {
  250.                 f1=sh_open1(s2,O_RDONLY | O_BINARY);
  251.               }
  252.             }
  253.             if (f1>=0) {
  254.               u.numbytes = filelength(f1);
  255.               sh_close(f1);
  256.               get_file_idz(&u,batch[i1].dir);
  257.               ++thisuser.uploaded;
  258.               modify_database(u.filename,1);
  259.               thisuser.uk += (int) (bytes_to_k(u.numbytes));
  260.               lock_status();
  261.               ++status.uptoday;
  262.               ++status.filechange[filechange_upload];
  263.               save_status();
  264.               f=sh_open(dlfn,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  265.               SETREC(f,rn);
  266.               sh_write(f,(void *)&u,sizeof(uploadsrec));
  267.               f=sh_close(f);
  268.               sprintf(s,get_stringx(1,54),
  269.                 u.filename,
  270.                 directories[batch[i1].dir].name, cps);
  271.               sysoplog(s);
  272.               outstr(get_string(866));
  273.               outstr(u.filename);
  274.               outstr(get_string(867));
  275.               pl(directories[batch[i1].dir].name);
  276.             }
  277.           }
  278.           delbatch(i1);
  279.           return;
  280.         }
  281.       }
  282.       delbatch(i1);
  283.       if (try_to_ul(fn)) {
  284.         sprintf(s,get_stringx(1,55), fn);
  285.         sysoplog(s);
  286.         outstr(get_string(868));
  287.         pl(fn);
  288.       }
  289.  
  290.       return;
  291.     }
  292.   }
  293.   if (try_to_ul(fn)) {
  294.     sprintf(s,get_stringx(1,56),fn);
  295.     sysoplog(s);
  296.     outstr(get_string(869));
  297.     pl(fn);
  298.     sprintf(s,"%s%s",syscfgovr.batchdir, fn);
  299.     unlink(s);
  300.   }
  301. }
  302.  
  303. /****************************************************************************/
  304.  
  305. void ymbatchdl(int had)
  306. {
  307.   int rr,i,ok,cur=0,f;
  308.   char s[161],s1[81];
  309.   uploadsrec u;
  310.   double percent;
  311.  
  312.   if (!incom)
  313.     return;
  314.   sprintf(s,get_stringx(1,57),numbatchdl, ctim(batchtime));
  315.   if (had)
  316.     strcat(s,get_stringx(1,58));
  317.   sysoplog(s);
  318.   nl();
  319.   pl(s);
  320.   nl();
  321.  
  322.   rr=0;
  323.   do {
  324.     tleft(1);
  325.     if ((syscfg.req_ratio>0.0001) && (ratio()<syscfg.req_ratio))
  326.       rr=1;
  327.     if (thisuser.exempt & exempt_ratio)
  328.       rr=0;
  329.     if (!batch[cur].sending) {
  330.       rr=0;
  331.       ++cur;
  332.     }
  333.     if ((nsl()>=batch[cur].time) && (!rr)) {
  334.       dliscan1(batch[cur].dir);
  335.       i=recno(batch[cur].filename);
  336.       if (i<=0) {
  337.         delbatch(cur);
  338.       } else {
  339.         sprintf(s,get_stringx(1,59),numbatchdl,ctim(batchtime));
  340.         outs(s);
  341.         f=sh_open(dlfn,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  342.         SETREC(f,i);
  343.         sh_read(f,(void *)&u,sizeof(uploadsrec));
  344.         f=sh_close(f);
  345.         sprintf(s,"%s%s",directories[batch[cur].dir].path,u.filename);
  346.         if(directories[batch[cur].dir].mask & mask_cdrom) {
  347.           sprintf(s1,"%s%s",
  348.             directories[batch[cur].dir].path,u.filename);
  349.           sprintf(s,"%s%s",
  350.             syscfgovr.tempdir,u.filename);
  351.           if (!exist(s))
  352.             copy_file(s1,s);
  353.         }
  354.         write_inst(INST_LOC_DOWNLOAD,udir[curdir].subnum,INST_FLAGS_NONE);
  355.         xymodem_send(s,&ok,&percent,u.filetype,1,1,1);
  356.         if (ok) {
  357.           downloaded(u.filename, 0);
  358.         } else {
  359.         }
  360.       }
  361.     } else
  362.       delbatch(cur);
  363.   } while ((ok) && (!hangup) && (numbatch>cur) && (!rr));
  364.   if ((ok) && (!hangup))
  365.     endbatch();
  366.   if (rr) {
  367.     nl();
  368.     pl(get_string(870));
  369.     nl();
  370.   }
  371.   if (had) {
  372.     bihangup(0);
  373.   }
  374. }
  375.  
  376. /****************************************************************************/
  377.  
  378. void handle_dszline(char *l)
  379. {
  380.   char *ss;
  381.   int i;
  382.   long cps;
  383.   char s[161];
  384.  
  385.   /* find the filename */
  386.   ss=strtok(l," \t");
  387.   for (i=0; (i<10) && (ss); i++) {
  388.     switch(i) {
  389.       case 4: cps=atol(ss); break;
  390.     }
  391.     ss=strtok(NULL," \t");
  392.   }
  393.  
  394.   if (ss) {
  395.     strcpy(s,stripfn(ss));
  396.     align(s);
  397.  
  398.     switch(*l) {
  399.       case 'Z':
  400.       case 'r':
  401.       case 'R':
  402.       case 'B':
  403.       case 'H':
  404.         /* received a file */
  405.         uploaded(s,cps);
  406.         break;
  407.  
  408.       case 'z':
  409.       case 's':
  410.       case 'S':
  411.       case 'b':
  412.       case 'h':
  413.       case 'Q':
  414.         /* sent a file */
  415.         downloaded(s,cps);
  416.         break;
  417.  
  418.       case 'E':
  419.       case 'e':
  420.       case 'L':
  421.       case 'l':
  422.       case 'U':
  423.         /* error */
  424.         sprintf(s,get_stringx(1,60),ss);
  425.         sysoplog(s);
  426.         break;
  427.     }
  428.   }
  429. }
  430.  
  431. /****************************************************************************/
  432.  
  433. double ratio1(long a)
  434. {
  435.   double r;
  436.  
  437.   if ((thisuser.dk==0) && (a==0))
  438.     return(99.999);
  439.   r=((float) thisuser.uk) / ((float) (thisuser.dk + a));
  440.   if (r>99.998)
  441.     r=99.998;
  442.   return(r);
  443. }
  444.  
  445. /****************************************************************************/
  446.  
  447. void make_ul_batch_list(char *listfn)
  448. {
  449.   int f,i;
  450.   char s[255],s1[81];
  451.  
  452.   if(instance > 1)
  453.     sprintf(listfn,"%s\\FILESUL.%3.3d",cdir,instance);
  454.   else
  455.     sprintf(listfn,"%s\\FILES.UL",cdir);
  456.  
  457.   _chmod(listfn,1,0);
  458.   unlink(listfn);
  459.  
  460.   f=sh_open(listfn,O_RDWR | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
  461.   if (f<0) {
  462.     listfn[0]=0;
  463.     return;
  464.   }
  465.  
  466.   for (i=0; i<numbatch; i++) {
  467.     if (!batch[i].sending) {
  468.       cd_to(directories[batch[i].dir].path);
  469.       get_dir(s1,1);
  470.       cd_to(cdir);
  471.       sprintf(s,"%s%s\r\n",s1,stripfn(batch[i].filename));
  472.       sh_write(f,s,strlen(s));
  473.     }
  474.   }
  475.   sh_close(f);
  476. }
  477.  
  478. /****************************************************************************/
  479.  
  480. void make_dl_batch_list(char *listfn)
  481. {
  482.   char s[255],s1[81],s2[81];
  483.   int i, f, ok;
  484.   double at=0.0;
  485.   long addk=0,thisk;
  486.  
  487.   if(instance > 1)
  488.     sprintf(listfn,"%s\\FILESDL.%3.3d",cdir,instance);
  489.   else
  490.     sprintf(listfn,"%s\\FILES.DL",cdir);
  491.  
  492.   _chmod(listfn,1,0);
  493.   unlink(listfn);
  494.  
  495.   f=sh_open(listfn,O_RDWR | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
  496.   if (f<0) {
  497.     listfn[0]=0;
  498.     return;
  499.   }
  500.  
  501.   for (i=0; i<numbatch; i++) {
  502.     if (batch[i].sending) {
  503.       if(directories[batch[i].dir].mask & mask_cdrom) {
  504.         cd_to(syscfgovr.tempdir);
  505.         get_dir(s1,1);
  506.         sprintf(s,"%s%s",s1,stripfn(batch[i].filename));
  507.         if(!exist(s)) {
  508.           cd_to(directories[batch[i].dir].path);
  509.           get_dir(s2,1);
  510.           strcat(s2,stripfn(batch[i].filename));
  511.           copy_file(s2,s);
  512.         }
  513.         strcat(s,"\r\n");
  514.       } else {
  515.         cd_to(directories[batch[i].dir].path);
  516.         get_dir(s1,1);
  517.         sprintf(s,"%s%s\r\n",s1,stripfn(batch[i].filename));
  518.       }
  519.       ok=1;
  520.       cd_to(cdir);
  521.       if (nsl() < (batch[i].time + at)) {
  522.         ok=0;
  523.         npr("%s%s%s\r\n",
  524.             get_string(1478),
  525.             batch[i].filename,
  526.             get_string(1479));
  527.       }
  528.       thisk=bytes_to_k(batch[i].len);
  529.       if ((syscfg.req_ratio>0.0001) && (ratio1(addk+thisk)<syscfg.req_ratio) &&
  530.           (!(thisuser.exempt & exempt_ratio))) {
  531.         ok=0;
  532.         npr("%s%s%s\r\n",
  533.             get_string(1478),
  534.             batch[i].filename,
  535.             get_string(1480));
  536.       }
  537.       if (ok) {
  538.         sh_write(f,s,strlen(s));
  539.         at += batch[i].time;
  540.         addk += thisk;
  541.       }
  542.     }
  543.   }
  544.   sh_close(f);
  545. }
  546.  
  547. /****************************************************************************/
  548.  
  549. void run_cmd(char *cmdln, char *downlist, char *uplist, char *dl, int had)
  550. {
  551.   char sx1[21], sx2[21], sx3[21], s[161];
  552.  
  553.   ultoa(com_speed,sx1,10);
  554.   if ((com_speed==1) || (com_speed==49664))
  555.     strcpy(sx1,"115200");
  556.   ultoa(modem_speed,sx3,10);
  557.   sx2[0]='0'+syscfgovr.primaryport;
  558.   sx2[1]=0;
  559.   stuff_in(s,cmdln,sx1,sx2,downlist,sx3,uplist);
  560.   if (s[0]) {
  561.     make_abs_cmd(s);
  562.     clrscrb();
  563.     outs(dl);
  564.     outs("\r\n");
  565.     outs(s);
  566.     outs("\r\n");
  567.     if (incom) {
  568.       _chmod(dszlog,1,0);
  569.       unlink(dszlog);
  570.  
  571.       create_chain_file();
  572.  
  573.       cd_to(syscfgovr.batchdir);
  574.  
  575.       extern_prog(s, sysinfo.spawn_opts[7]);
  576.  
  577.       cd_to(cdir);
  578.  
  579.       if (had) {
  580.         bihangup(1);
  581.         if (!cdet()) {
  582.           dtr(1);
  583.           wait1(5);
  584.           holdphone(1);
  585.         }
  586.       } else {
  587.         nl();
  588.         pl(get_string(26));
  589.         nl();
  590.       }
  591.  
  592.       process_dszlog();
  593.  
  594.       topscreen();
  595.     }
  596.   }
  597.  
  598.   if (downlist[0]) {
  599.     _chmod(downlist,1,0);
  600.     unlink(downlist);
  601.   }
  602.   if (uplist[0]) {
  603.     _chmod(uplist,1,0);
  604.     unlink(uplist);
  605.   }
  606. }
  607.  
  608. /****************************************************************************/
  609.  
  610. void process_dszlog(void)
  611. {
  612.   int f,i,i1;
  613.   char *ss;
  614.   char **lines;
  615.  
  616.   lines = (char **)malloca(sysinfo.max_batch * sizeof(char *) * 2);
  617.  
  618.   if (!lines)
  619.     return;
  620.  
  621.   f=sh_open1(dszlog,O_RDONLY | O_BINARY);
  622.   if (f>0) {
  623.     i1=(int)filelength(f);
  624.     ss=malloca(i1);
  625.     if (ss) {
  626.       i=sh_read(f,ss,i1);
  627.       if (i>0) {
  628.         ss[i]=0;
  629.         lines[0]=strtok(ss,"\r\n");
  630.         for (i=1; (i<sysinfo.max_batch*2-2) && (lines[i-1]); i++)
  631.           lines[i]=strtok(NULL,"\n");
  632.  
  633.         lines[sysinfo.max_batch*2-2]=NULL;
  634.  
  635.         for (i1=0; lines[i1]; i1++) {
  636.           handle_dszline(lines[i1]);
  637.         }
  638.  
  639.       }
  640.       bbsfree(ss);
  641.     }
  642.     sh_close(f);
  643.   }
  644.  
  645.   bbsfree(lines);
  646. }
  647.  
  648. /****************************************************************************/
  649.  
  650. void dszbatchdl(int had, char *cmdln, char *desc)
  651. {
  652.   char listfn[81],dl[161];
  653.  
  654.   sprintf(dl,get_stringx(1,61),
  655.           desc, numbatchdl, ctim(batchtime));
  656.   if (had)
  657.     strcat(dl,get_stringx(1,58));
  658.   sysoplog(dl);
  659.   nl();
  660.   pl(dl);
  661.   nl();
  662.  
  663.   write_inst(INST_LOC_DOWNLOAD,udir[curdir].subnum,INST_FLAGS_NONE);
  664.   make_dl_batch_list(listfn);
  665.   run_cmd(cmdln, listfn, "", dl, had);
  666. }
  667.  
  668. /****************************************************************************/
  669.  
  670. void dszbatchul(int had, char *cmdln, char *desc)
  671. {
  672.   char listfn[81],dl[161];
  673.   double ti;
  674.  
  675.   sprintf(dl,get_stringx(1,62), desc, numbatch-numbatchdl);
  676.   if (had)
  677.     strcat(dl,get_stringx(1,58));
  678.   sysoplog(dl);
  679.   nl();
  680.   pl(dl);
  681.   nl();
  682.  
  683.   write_inst(INST_LOC_UPLOAD,udir[curdir].subnum,INST_FLAGS_NONE);
  684.   make_ul_batch_list(listfn);
  685.  
  686.   ti=timer();
  687.   run_cmd(cmdln, "", listfn, dl, had);
  688.   ti=timer()-ti;
  689.   if (ti<0)
  690.     ti += 24.0*3600.0;
  691.   thisuser.extratime += ti;
  692. }
  693.  
  694. /****************************************************************************/
  695.  
  696. void bibatch(int had, char *cmdln, char *desc)
  697. {
  698.   char listfn[81], listfn1[81], dl[161];
  699.   double ti;
  700.  
  701.   sprintf(dl,get_stringx(1,63),
  702.     desc, numbatchdl, numbatch-numbatchdl);
  703.   if (had)
  704.     strcat(dl,get_stringx(1,58));
  705.   sysoplog(dl);
  706.   nl();
  707.   pl(dl);
  708.   nl();
  709.  
  710.   write_inst(INST_LOC_BIXFER,udir[curdir].subnum,INST_FLAGS_NONE);
  711.   make_ul_batch_list(listfn);
  712.   make_dl_batch_list(listfn1);
  713.  
  714.   ti=timer();
  715.   run_cmd(cmdln, listfn1, listfn, dl, had);
  716.   ti=timer()-ti;
  717.   if (ti<0)
  718.     ti += 24.0*3600.0;
  719.   /* Hmm... */
  720.   /* thisuser.extratime += ti; */
  721. }
  722.  
  723. /****************************************************************************/
  724.  
  725. void batchdl(int mode)
  726. {
  727.   int i,done,had,otag;
  728.   char s[81],ch;
  729.  
  730.   done=0;
  731.   if (numbatch==0) {
  732.     nl();
  733.     pl(get_string(871));
  734.     nl();
  735.     return;
  736.   }
  737.   otag=tagging;
  738.   tagging=0;
  739.   do {
  740.     switch(mode) {
  741.       case 0:
  742.         nl();
  743.         if (menu_on()) {
  744.           rip_saveall();
  745.           printmenu(9);
  746.         } else
  747.           prt(2,get_string(872));
  748.         ch=onek("Q?CLRDUB");
  749.         if (menu_on())
  750.           rip_restoreall();
  751.       break;
  752.       case 1:
  753.         listbatch();
  754.         ch='D';
  755.       break;
  756.       case 2:
  757.         listbatch();
  758.         ch='U';
  759.       break;
  760.     }
  761.     switch(ch) {
  762.       case '?':
  763.         printmenu(9);
  764.         break;
  765.       case 'Q':
  766.         done=1;
  767.         break;
  768.       case 'L':
  769.         listbatch();
  770.         break;
  771.       case 'R':
  772.         nl();
  773.         prt(2,get_string(724));
  774.         input(s,4);
  775.         i=atoi(s);
  776.         if ((i>0) && (i<=numbatch)) {
  777.           didnt_upload(i-1);
  778.           delbatch(i-1);
  779.         }
  780.         if (numbatch==0) {
  781.           nl();
  782.           pl(get_string(873));
  783.           nl();
  784.           done=1;
  785.         }
  786.         break;
  787.       case 'C':
  788.         prt(5,get_string(874));
  789.         if (yn()) {
  790.           for (i=0; i<numbatch; i++)
  791.             didnt_upload(i);
  792.           numbatch=0;
  793.           numbatchdl=0;
  794.           batchtime=0.0;
  795.           done=1;
  796.           pl(get_string(875));
  797.         }
  798.         done=1;
  799.         break;
  800.       case 'U':
  801.         if (numbatchdl==numbatch) {
  802.           nl();
  803.           pl(get_string(876));
  804.           nl();
  805.           break;
  806.         }
  807.         nl();
  808.         prt(5,get_string(877));
  809.         had=yn();
  810.         nl();
  811.  
  812.         i=get_protocol(xf_up_batch);
  813.         if (i>0) {
  814.  
  815.           dszbatchul(had, externs[i-6].receivebatchfn, externs[i-6].description);
  816.  
  817.           if (!had) {
  818.             nl();
  819.             outstr(get_string(782));
  820.             npr("%-6.3f\r\n",ratio());
  821.           }
  822.         }
  823.         done=1;
  824.         break;
  825.       case 'B':
  826.         if (modem_flag & flag_as) {
  827.           nl();
  828.           pl(get_string(878));
  829.           pl(get_string(879));
  830.           pl(get_string(880));
  831.           nl();
  832.           prt(5,get_string(881));
  833.           if (!yn()) {
  834.             done=1;
  835.             break;
  836.           }
  837.         }
  838.         nl();
  839.         prt(5,get_string(877));
  840.         had=yn();
  841.         nl();
  842.  
  843.         i=get_protocol(xf_bi);
  844.         if (i>0) {
  845.  
  846.           bibatch(had, externs[i-6].bibatchfn, externs[i-6].description);
  847.  
  848.           if (!had) {
  849.             nl();
  850.             outstr(get_string(782));
  851.             npr("%-6.3f\r\n",ratio());
  852.           }
  853.         }
  854.         done=1;
  855.         break;
  856.       case 'D':
  857.         if (numbatchdl==0) {
  858.           nl();
  859.           pl(get_string(882));
  860.           nl();
  861.           done=1;
  862.           break;
  863.         }
  864.  
  865.         nl();
  866.         if (!ratio_ok()) {
  867.           nl();
  868.           pl(get_string(883));
  869.           nl();
  870.           done=1;
  871.           break;
  872.         }
  873.         nl();
  874.         prt(5,get_string(877));
  875.         had=yn();
  876.         nl();
  877.  
  878.         i=get_protocol(xf_down_batch);
  879.         if (i>0) {
  880.  
  881.           if (i==4) {
  882.             if (over_intern && (over_intern[2].othr & othr_override_internal) &&
  883.                 (over_intern[2].sendbatchfn[0]))
  884.               dszbatchdl(had, over_intern[2].sendbatchfn, prot_name(4));
  885.             else
  886.               ymbatchdl(had);
  887.           } else
  888.             dszbatchdl(had,externs[i-6].sendbatchfn, externs[i-6].description);
  889.  
  890.           if (!had) {
  891.             nl();
  892.             outstr(get_string(782));
  893.             npr("%-6.3f\r\n",ratio());
  894.           }
  895.         }
  896.         done=1;
  897.         break;
  898.     }
  899.   } while ((!done) && (!hangup));
  900.   tagging=otag;
  901. }
  902.  
  903. /****************************************************************************/
  904.  
  905.  
  906. void bihangup(int up)
  907. /* This function returns one character from either the local keyboard or
  908.  * remote com port (if applicable).  Every second of inactivity, a
  909.  * beep is sounded.  After 10 seconds of inactivity, the user is hung up.
  910.  */
  911. {
  912.   unsigned char ch;
  913.   long nextbeep;
  914.   long dd;
  915.   int color=5;
  916.  
  917.   timelastchar1=timer1();
  918.   nextbeep=18L;
  919.   nl();
  920.   outstr(get_string(1481));
  921.   nl();
  922.   outstr(get_string(1482));
  923.   npr("%d%d  %c",color,(int)(182L/nextbeep),7);
  924.   do {
  925.     while (empty() && !hangup) {
  926.       dd = timer1();
  927.       if (labs(dd - timelastchar1) > 65536L) {
  928.         nextbeep -= 1572480L;
  929.         timelastchar1 -= 1572480L;
  930.       }
  931.       if ((dd - timelastchar1) > nextbeep) {
  932.         npr("\r%d%d  %c",color,(182L-nextbeep)/18L,7);
  933.         nextbeep += 18L;
  934.         if ((182L-nextbeep)/18L <= 6)
  935.           color=2;
  936.         if ((182L-nextbeep)/18L <= 3)
  937.           color=6;
  938.       }
  939.       if (labs(dd - timelastchar1) > 182L) {
  940.     nl();
  941.     outstr(get_string(1483));
  942.     nl();
  943.         dtr(0);
  944.     hangup = 1;
  945.         if(up) {
  946.           wait1(2);
  947.           if (!cdet()) {
  948.             dtr(1);
  949.             wait1(2);
  950.             holdphone(1);
  951.           }
  952.         }
  953.       }
  954.       giveup_timeslice();
  955.       checkhangup();
  956.     }
  957.     ch = inkey();
  958.     if ((ch=='h') || (ch=='H'))
  959.       hangup=1;
  960.   } while (!ch && !hangup);
  961. }
  962.