home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / WWIV2.ZIP / BATCH.C next >
Text File  |  1993-06-01  |  17KB  |  797 lines

  1. #include "vars.h"
  2. #pragma hdrstop
  3. #include <dir.h>
  4. #define SETREC(i)  lseek(dlf,((long) (i))*((long)sizeof(uploadsrec)),SEEK_SET);
  5.  
  6. void listbatch(void)
  7. {
  8.   char s[81];
  9.   int abort,i;
  10.  
  11.   abort=0;
  12.   nl();
  13.   ansic(1);
  14.   outstr(get_string(864));
  15.   npr("%d  ",numbatch);
  16.   if (numbatchdl) {
  17.     outstr(get_string(865));
  18.     pl(ctim(batchtime));
  19.   } else
  20.     nl();
  21.   nl();
  22.   for (i=0; (i<numbatch) && (!abort) && (!hangup); i++) {
  23.     if (batch[i].sending)
  24.       sprintf(s,"1%d7. (1D7) 1%s   %s  %s",i+1, batch[i].filename,
  25.       ctim(batch[i].time),
  26.       directories[batch[i].dir].name);
  27.     else
  28.       sprintf(s,"1%d7. (1U7) 1%s             %s",i+1,batch[i].filename,
  29.       directories[batch[i].dir].name);
  30.  
  31.     pla(s,&abort);
  32.   }
  33. }
  34.  
  35. void delbatch(int i)
  36. {
  37.   int i1;
  38.  
  39.   if (i<numbatch) {
  40.     if (batch[i].sending) {
  41.       batchtime -= batch[i].time;
  42.       --numbatchdl;
  43.     }
  44.     --numbatch;
  45.     for (i1=i; i1<=numbatch; i1++) {
  46.       batch[i1]=batch[i1+1];
  47.     }
  48.   }
  49. }
  50.  
  51. void downloaded(char *fn, long cps)
  52. {
  53.   int i,i1;
  54.   uploadsrec u;
  55.   char s[81];
  56.  
  57.   for (i1=0; i1<numbatch; i1++) {
  58.     if ((strcmp(fn,batch[i1].filename)==0) && (batch[i1].sending)) {
  59.       dliscan1(batch[i1].dir);
  60.       i=recno((batch[i1].filename));
  61.       if (i>0) {
  62.         SETREC(i);
  63.         read(dlf,(void *)&u,sizeof(uploadsrec));
  64.         ++thisuser.downloaded;
  65.         thisuser.dk += (int) ((u.numbytes+1023)/1024);
  66.         ++u.numdloads;
  67.         SETREC(i);
  68.         write(dlf,(void *)&u,sizeof(uploadsrec));
  69.     if (cps)
  70.       sprintf(s,get_stringx(1,50),u.filename, cps);
  71.     else
  72.       sprintf(s,get_stringx(1,43),u.filename);
  73.     sysoplog(s);
  74.     if (syscfg.sysconfig & sysconfig_log_dl) {
  75.       sprintf(s,get_stringx(1,51),
  76.             nam(&thisuser,usernum), u.filename, date());
  77.           ssm(u.ownerusr,0,s);
  78.         }
  79.       }
  80.       closedl();
  81.       delbatch(i1);
  82.  
  83.       return;
  84.     }
  85.   }
  86.   sprintf(s,get_stringx(1,52),fn);
  87.   sysoplog(s);
  88. }
  89.  
  90. void didnt_upload(int ind)
  91. {
  92.   int i,i1;
  93.   char s[81];
  94.   uploadsrec u;
  95.  
  96.   if (batch[ind].sending)
  97.     return;
  98.  
  99.   dliscan1(batch[ind].dir);
  100.   i=recno(batch[ind].filename);
  101.   if (i>0) {
  102.     do {
  103.       SETREC(i);
  104.       read(dlf, &u, sizeof(uploadsrec));
  105.       if (u.numbytes!=0)
  106.         i=nrecno(batch[ind].filename, i);
  107.     } while ((i!=-1) && (u.numbytes!=0));
  108.  
  109.     if ((i!=-1) && (u.numbytes==0)) {
  110.       if (u.mask & mask_extended)
  111.         delete_extended_description(u.filename);
  112.       for (i1=i; i1<numf; i1++) {
  113.         SETREC(i1+1);
  114.         read(dlf,(void *)&u,sizeof(uploadsrec));
  115.         SETREC(i1);
  116.         write(dlf,(void *)&u,sizeof(uploadsrec));
  117.       }
  118.       --i;
  119.       --numf;
  120.       SETREC(0);
  121.       read(dlf, &u, sizeof(uploadsrec));
  122.       u.numbytes=numf;
  123.       SETREC(0);
  124.       write(dlf,(void *)&u,sizeof(uploadsrec));
  125.       closedl();
  126.       return;
  127.     }
  128.   }
  129.   sprintf(s,get_stringx(1,53),batch[ind].filename);
  130.   sysoplog(s);
  131.  
  132.   closedl();
  133. }
  134.  
  135. int try_to_ul(char *fn)
  136. {
  137.  
  138.   if (hangup)
  139.     return(1);
  140.  
  141.   if (!okfn(fn))
  142.     return(1);
  143.  
  144.   /* future expansion here */
  145.  
  146.   /* yes, this should be return(1) until there is code above to prompt the */
  147.   /* user for the file's info, and to handle uploading it */
  148.   return(1);
  149. }
  150.  
  151. void uploaded(char *fn, long cps)
  152. {
  153.   int i,i1, d1, d2, rn;
  154.   uploadsrec u;
  155.   char s[81], s1[81], s2[81];
  156.   char *b;
  157.  
  158.   for (i1=0; i1<numbatch; i1++) {
  159.     if ((strcmp(fn,batch[i1].filename)==0) && (!batch[i1].sending)) {
  160.       dliscan1(batch[i1].dir);
  161.       rn=recno((batch[i1].filename));
  162.       if (rn>0) {
  163.         do {
  164.           SETREC(rn);
  165.           read(dlf, &u, sizeof(uploadsrec));
  166.           if (u.numbytes!=0)
  167.             rn=nrecno(batch[i1].filename, rn);
  168.         } while ((rn!=-1) && (u.numbytes!=0));
  169.  
  170.         if ((rn!=-1) && (u.numbytes==0)) {
  171.  
  172.           sprintf(s1,"%s%s",syscfg.batchdir, fn);
  173.           sprintf(s2,"%s%s", directories[batch[i1].dir].path, fn);
  174.  
  175.           if ((strcmp(s1,s2)!=0) && (exist(s1))) {
  176.             d2=0;
  177.             if ((s1[1]!=':') && (s2[1]!=':'))
  178.               d2=1;
  179.             if ((s1[1]==':') && (s2[1]==':') && (s1[0]==s2[0]))
  180.               d2=1;
  181.             if (d2) {
  182.               rename(s1,s2);
  183.               unlink(s1);
  184.             } else {
  185.               if ((b=malloca(16400))==NULL)
  186.                 return;
  187.               d1=open(s1,O_RDONLY | O_BINARY);
  188.               d2=open(s2,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  189.               i=read(d1,(void *)b,16384);
  190.               while (i>0) {
  191.                 write(d2,(void *)b,i);
  192.                 i=read(d1,(void *)b,16384);
  193.               }
  194.               close(d1);
  195.               close(d2);
  196.               unlink(s1);
  197.               farfree(b);
  198.             }
  199.           }
  200.  
  201.           d1=open(s2,O_RDONLY | O_BINARY);
  202.           if (d1>0) {
  203.             if (syscfg.upload_c[0]) {
  204.               close(d1);
  205.               if (check_ul_event(batch[i1].dir, &u)) {
  206.                 closedl();
  207.                 didnt_upload(i1);
  208.                 delbatch(i1);
  209.                 d1=-1;
  210.               } else {
  211.                 d1=open(s2,O_RDONLY | O_BINARY);
  212.               }
  213.             }
  214.             if (d1>=0) {
  215.               u.numbytes = filelength(d1);
  216.               close(d1);
  217.  
  218.               ++thisuser.uploaded;
  219.               thisuser.uk += (int) ((u.numbytes+1023)/1024);
  220.               ++status.uptoday;
  221.               save_status();
  222.               SETREC(rn);
  223.               write(dlf,(void *)&u,sizeof(uploadsrec));
  224.               sprintf(s,get_stringx(1,54),
  225.                 u.filename,
  226.                 directories[batch[i1].dir].name, cps);
  227.           sysoplog(s);
  228.           ansic(1);
  229.           outstr(get_string(866));
  230.           ansic(7);
  231.           outstr(u.filename);
  232.           ansic(1);
  233.           outstr(get_string(867));
  234.           ansic(7);
  235.           pl(directories[batch[i1].dir].name);
  236.         }
  237.           }
  238.           closedl();
  239.           delbatch(i1);
  240.           return;
  241.         }
  242.       }
  243.       closedl();
  244.       delbatch(i1);
  245.       if (try_to_ul(fn)) {
  246.         sprintf(s,get_stringx(1,55), fn);
  247.     sysoplog(s);
  248.     ansic(6);
  249.     outstr(get_string(868));
  250.     pl(fn);
  251.       }
  252.  
  253.       return;
  254.     }
  255.   }
  256.   if (try_to_ul(fn)) {
  257.     sprintf(s,get_stringx(1,56),fn);
  258.     sysoplog(s);
  259.     ansic(6);
  260.     outstr(get_string(869));
  261.     pl(fn);
  262.     sprintf(s,"%s%s",syscfg.batchdir, fn);
  263.     unlink(s);
  264.   }
  265. }
  266.  
  267. void ymbatchdl(int had)
  268. {
  269.   int rr,i,ok,cur=0;
  270.   char s[81];
  271.   uploadsrec u;
  272.   double percent;
  273.  
  274.   if (!incom)
  275.     return;
  276.   sprintf(s,get_stringx(1,57),numbatchdl, ctim(batchtime));
  277.   if (had)
  278.     strcat(s,get_stringx(1,58));
  279.   sysoplog(s);
  280.   nl();
  281.   pl(s);
  282.   nl();
  283.  
  284.   rr=0;
  285.   do {
  286.     tleft(1);
  287.     if ((syscfg.req_ratio>0.0001) && (ratio()<syscfg.req_ratio))
  288.       rr=1;
  289.     if (thisuser.exempt & exempt_ratio)
  290.       rr=0;
  291.     if (!batch[cur].sending) {
  292.       rr=0;
  293.       ++cur;
  294.     }
  295.     if ((nsl()>=batch[cur].time) && (!rr)) {
  296.       dliscan1(batch[cur].dir);
  297.       i=recno(batch[cur].filename);
  298.       if (i<=0) {
  299.         delbatch(cur);
  300.         closedl();
  301.       } else {
  302.         sprintf(s,get_stringx(1,59),numbatchdl,ctim(batchtime));
  303.         outs(s);
  304.         SETREC(i);
  305.         read(dlf,(void *)&u,sizeof(uploadsrec));
  306.         closedl();
  307.         sprintf(s,"%s%s",directories[batch[cur].dir].path,u.filename);
  308.         xymodem_send(s,&ok,&percent,u.filetype,1,1,1);
  309.         if (ok) {
  310.           downloaded(u.filename, 0);
  311.         } else {
  312.           closedl();
  313.         }
  314.       }
  315.     } else
  316.       delbatch(cur);
  317.   } while ((ok) && (!hangup) && (numbatch>cur) && (!rr));
  318.   if ((ok) && (!hangup))
  319.     endbatch();
  320.   if (rr) {
  321.     nl();
  322.     ansic(6);
  323.     pl(get_string(870));
  324.     nl();
  325.   }
  326.   if (had) {
  327.     dtr(0);
  328.     hangup=1;
  329.   }
  330. }
  331.  
  332. void handle_dszline(char *l)
  333. {
  334.   char *ss;
  335.   int i;
  336.   long cps;
  337.   char s[161];
  338.  
  339.   /* find the filename */
  340.   ss=strtok(l," \t");
  341.   for (i=0; (i<10) && (ss); i++) {
  342.     switch(i) {
  343.       case 4: cps=atol(ss); break;
  344.     }
  345.     ss=strtok(NULL," \t");
  346.   }
  347.  
  348.   if (ss) {
  349.     strcpy(s,stripfn(ss));
  350.     align(s);
  351.  
  352.     switch(*l) {
  353.       case 'Z':
  354.       case 'r':
  355.       case 'R':
  356.       case 'B':
  357.       case 'H':
  358.         /* received a file */
  359.         uploaded(s,cps);
  360.         break;
  361.  
  362.       case 'z':
  363.       case 's':
  364.       case 'S':
  365.       case 'b':
  366.       case 'h':
  367.         /* sent a file */
  368.         downloaded(s,cps);
  369.         break;
  370.  
  371.       case 'E':
  372.       case 'e':
  373.       case 'L':
  374.       case 'l':
  375.       case 'U':
  376.         /* error */
  377.         sprintf(s,get_stringx(1,60),ss);
  378.         sysoplog(s);
  379.         break;
  380.     }
  381.   }
  382. }
  383.  
  384. double ratio1(long a)
  385. {
  386.   double r;
  387.  
  388.   if ((thisuser.dk==0) && (a==0))
  389.     return(99.999);
  390.   r=((float) thisuser.uk) / ((float) (thisuser.dk + a));
  391.   if (r>99.998)
  392.     r=99.998;
  393.   return(r);
  394. }
  395.  
  396. void make_ul_batch_list(char *listfn)
  397. {
  398.   int f,i;
  399.   char s[255],s1[81];
  400.  
  401.   sprintf(listfn,"%s\\FILES.UL",cdir);
  402.  
  403.   _chmod(listfn,1,0);
  404.   unlink(listfn);
  405.  
  406.   f=open(listfn,O_RDWR | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
  407.   if (f<0) {
  408.     listfn[0]=0;
  409.     return;
  410.   }
  411.  
  412.   for (i=0; i<numbatch; i++) {
  413.     if (!batch[i].sending) {
  414.       cd_to(directories[batch[i].dir].path);
  415.       get_dir(s1,1);
  416.       cd_to(cdir);
  417.       sprintf(s,"%s%s\r\n",s1,stripfn(batch[i].filename));
  418.       write(f,s,strlen(s));
  419.     }
  420.   }
  421.   close(f);
  422. }
  423.  
  424. void make_dl_batch_list(char *listfn)
  425. {
  426.   char s[255],s1[81];
  427.   int i, f, ok;
  428.   double at=0.0;
  429.   long addk=0,thisk;
  430.  
  431.   sprintf(listfn,"%s\\FILES.DL",cdir);
  432.  
  433.   _chmod(listfn,1,0);
  434.   unlink(listfn);
  435.  
  436.   f=open(listfn,O_RDWR | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
  437.   if (f<0) {
  438.     listfn[0]=0;
  439.     return;
  440.   }
  441.  
  442.   for (i=0; i<numbatch; i++) {
  443.     if (batch[i].sending) {
  444.       cd_to(directories[batch[i].dir].path);
  445.       get_dir(s1,1);
  446.       cd_to(cdir);
  447.       sprintf(s,"%s%s\r\n",s1,stripfn(batch[i].filename));
  448.       ok=1;
  449.       if (nsl() < (batch[i].time + at))
  450.         ok=0;
  451.       thisk=(batch[i].len+1023)/1024;
  452.       if ((syscfg.req_ratio>0.0001) && (ratio1(addk+thisk)<syscfg.req_ratio) &&
  453.           (!(thisuser.exempt & exempt_ratio)))
  454.         ok=0;
  455.       if (ok) {
  456.         write(f,s,strlen(s));
  457.         at += batch[i].time;
  458.         addk += thisk;
  459.       }
  460.     }
  461.   }
  462.   close(f);
  463. }
  464.  
  465. void run_cmd(char *cmdln, char *downlist, char *uplist, char *dl, int had)
  466. {
  467.   char sx1[21], sx2[21], sx3[21], s[161];
  468.  
  469.   ultoa(com_speed,sx1,10);
  470.   ultoa(modem_speed,sx3,10);
  471.   sx2[0]='0'+syscfg.primaryport;
  472.   sx2[1]=0;
  473.   stuff_in(s,cmdln,sx1,sx2,downlist,sx3,uplist);
  474.   if (s[0]) {
  475.     make_abs_cmd(s);
  476.     clrscrb();
  477.     outs(dl);
  478.     outs("\r\n");
  479.     outs(s);
  480.     outs("\r\n");
  481.     if (incom) {
  482.       _chmod(dszlog,1,0);
  483.       unlink(dszlog);
  484.  
  485.       create_chain_file("CHAIN.TXT");
  486.  
  487.       cd_to(syscfg.batchdir);
  488.  
  489.       run_external1(s);
  490.  
  491.       cd_to(cdir);
  492.  
  493.       if (had) {
  494.         dtr(0);
  495.         hangup=1;
  496.         if (modem_flag & flag_ec)
  497.           wait1(36);
  498.         else
  499.           wait1(2);
  500.         if (!cdet()) {
  501.           dtr(1);
  502.           wait1(5);
  503.           holdphone(1);
  504.         }
  505.       } else {
  506.     nl();
  507.     ansic(7);
  508.     pl(get_string(26));
  509.     nl();
  510.       }
  511.  
  512.       process_dszlog();
  513.  
  514.       topscreen();
  515.     }
  516.   }
  517.  
  518.   if (downlist[0]) {
  519.     _chmod(downlist,1,0);
  520.     unlink(downlist);
  521.   }
  522.   if (uplist[0]) {
  523.     _chmod(uplist,1,0);
  524.     unlink(uplist);
  525.   }
  526. }
  527.  
  528. void process_dszlog(void)
  529. {
  530.   int f,i,i1;
  531.   char *ss;
  532.   char *lines[MAX_BATCH*2];
  533.  
  534.   f=open(dszlog,O_RDONLY | O_BINARY);
  535.   if (f>0) {
  536.     i1=(int)filelength(f);
  537.     ss=malloca(i1);
  538.     if (ss) {
  539.       i=read(f,ss,i1);
  540.       if (i>0) {
  541.         ss[i]=0;
  542.         lines[0]=strtok(ss,"\r\n");
  543.         for (i=1; (i<MAX_BATCH*2-2) && (lines[i-1]); i++)
  544.           lines[i]=strtok(NULL,"\n");
  545.  
  546.         lines[MAX_BATCH*2-2]=NULL;
  547.  
  548.         for (i1=0; lines[i1]; i1++) {
  549.           handle_dszline(lines[i1]);
  550.         }
  551.  
  552.       }
  553.       farfree(ss);
  554.     }
  555.     close(f);
  556.   }
  557. }
  558.  
  559. void dszbatchdl(int had, char *cmdln, char *desc)
  560. {
  561.   char listfn[81],dl[100];
  562.  
  563.  
  564.   sprintf(dl,get_stringx(1,61),
  565.           desc, numbatchdl, ctim(batchtime));
  566.   if (had)
  567.     strcat(dl,get_stringx(1,58));
  568.   sysoplog(dl);
  569.   nl();
  570.   pl(dl);
  571.   nl();
  572.  
  573.   make_dl_batch_list(listfn);
  574.  
  575.   run_cmd(cmdln, listfn, "", dl, had);
  576. }
  577.  
  578. void dszbatchul(int had, char *cmdln, char *desc)
  579. {
  580.   char listfn[81],dl[100];
  581.   int i,i1,f,ok;
  582.   double ti;
  583.  
  584.   sprintf(dl,get_stringx(1,62), desc, numbatch-numbatchdl);
  585.   if (had)
  586.     strcat(dl,get_stringx(1,58));
  587.   sysoplog(dl);
  588.   nl();
  589.   pl(dl);
  590.   nl();
  591.  
  592.   make_ul_batch_list(listfn);
  593.  
  594.   ti=timer();
  595.   run_cmd(cmdln, "", listfn, dl, had);
  596.   ti=timer()-ti;
  597.   if (ti<0)
  598.     ti += 24.0*3600.0;
  599.   thisuser.extratime += ti;
  600. }
  601.  
  602. /****************************************************************************/
  603.  
  604. void bibatch(int had, char *cmdln, char *desc)
  605. {
  606.   char listfn[81],dl[100], listfn1[81];
  607.   int i,i1,f,ok;
  608.   double ti;
  609.  
  610.   sprintf(dl,get_stringx(1,63),
  611.     desc, numbatchdl, numbatch-numbatchdl);
  612.   if (had)
  613.     strcat(dl,get_stringx(1,58));
  614.   sysoplog(dl);
  615.   nl();
  616.   pl(dl);
  617.   nl();
  618.  
  619.   make_ul_batch_list(listfn);
  620.   make_dl_batch_list(listfn1);
  621.  
  622.   ti=timer();
  623.   run_cmd(cmdln, listfn1, listfn, dl, had);
  624.   ti=timer()-ti;
  625.   if (ti<0)
  626.     ti += 24.0*3600.0;
  627.   /* Hmm... */
  628.   /* thisuser.extratime += ti; */
  629. }
  630.  
  631.  
  632. /****************************************************************************/
  633.  
  634.  
  635. void batchdl(void)
  636. {
  637.   int i,abort,done,i1,i2,had,dsz;
  638.   char s[81],s1[81],ch,ch1;
  639.  
  640.   done=0;
  641.   if (numbatch==0) {
  642.     nl();
  643.     ansic(6);
  644.     pl(get_string(871));
  645.     nl();
  646.     return;
  647.   }
  648.   do {
  649.     nl();
  650.     prt(1,"Batch7: 1L7,1R7,1Q7,1C7,1D7,1U7,1B7,1?7 > ");
  651.     ch=onek("Q?CLRDUB");
  652.     switch(ch) {
  653.       case '?':
  654.         printmenu(9);
  655.         break;
  656.       case 'Q':
  657.         done=1;
  658.         break;
  659.       case 'L':
  660.         listbatch();
  661.         break;
  662.       case 'R':
  663.     nl();
  664.     prt(1,get_string(724));
  665.     input(s,2);
  666.     i=atoi(s);
  667.     if ((i>0) && (i<=numbatch)) {
  668.       didnt_upload(i-1);
  669.       delbatch(i-1);
  670.     }
  671.     if (numbatch==0) {
  672.       nl();
  673.       ansic(1);
  674.       pl(get_string(873));
  675.           nl();
  676.           done=1;
  677.         }
  678.         break;
  679.       case 'C':
  680.     prt(5,get_string(874));
  681.     if (yn()) {
  682.       for (i=0; i<numbatch; i++)
  683.         didnt_upload(i);
  684.       numbatch=0;
  685.       numbatchdl=0;
  686.       batchtime=0.0;
  687.       done=1;
  688.       ansic(6);
  689.       pl(get_string(875));
  690.     }
  691.         break;
  692.       case 'U':
  693.         if (numbatchdl==numbatch) {
  694.       nl();
  695.       ansic(6);
  696.       pl(get_string(876));
  697.       nl();
  698.       break;
  699.     }
  700.     nl();
  701.     prt(5,get_string(877));
  702.     had=yn();
  703.     nl();
  704.  
  705.         i=get_protocol(xf_up_batch);
  706.         if (i>0) {
  707.  
  708.           dszbatchul(had, externs[i-6].receivebatchfn, externs[i-6].description);
  709.  
  710.           if (!had) {
  711.         nl();
  712.         ansic(1);
  713.         outstr(get_string(782));
  714.         npr("3%-6.3f\r\n",ratio());
  715.       }
  716.           done=1;
  717.         }
  718.         break;
  719.       case 'B':
  720.         if (modem_flag & flag_as) {
  721.       nl();
  722.       ansic(1);
  723.       pl(get_string(878));
  724.       pl(get_string(879));
  725.       pl(get_string(880));
  726.       nl();
  727.       prt(5,get_string(881));
  728.       if (!yn())
  729.         break;
  730.     }
  731.     nl();
  732.     prt(5,get_string(877));
  733.     had=yn();
  734.     nl();
  735.  
  736.         i=get_protocol(xf_bi);
  737.         if (i>0) {
  738.  
  739.           bibatch(had, externs[i-6].bibatchfn, externs[i-6].description);
  740.  
  741.           if (!had) {
  742.         nl();
  743.         ansic(1);
  744.         outstr(get_string(782));
  745.         npr("3%-6.3f\r\n",ratio());
  746.           }
  747.           done=1;
  748.         }
  749.         break;
  750.       case 'D':
  751.         if (numbatchdl==0) {
  752.       nl();
  753.       ansic(6);
  754.       pl(get_string(882));
  755.       nl();
  756.       break;
  757.     }
  758.  
  759.         nl();
  760.         if (!ratio_ok()) {
  761.       nl();
  762.       ansic(6);
  763.       pl(get_string(883));
  764.       nl();
  765.       break;
  766.     }
  767.  
  768.         nl();
  769.         prt(5,get_string(877));
  770.         had=yn();
  771.         nl();
  772.  
  773.         i=get_protocol(xf_down_batch);
  774.         if (i>0) {
  775.  
  776.           if (i==4) {
  777.             if (over_intern && (over_intern[2].othr & othr_override_internal) &&
  778.                 (over_intern[2].sendbatchfn[0]))
  779.               dszbatchdl(had, over_intern[2].sendbatchfn, prot_name(4));
  780.             else
  781.               ymbatchdl(had);
  782.           } else
  783.             dszbatchdl(had,externs[i-6].sendbatchfn, externs[i-6].description);
  784.  
  785.           if (!had) {
  786.         nl();
  787.         ansic(1);
  788.         outstr(get_string(782));
  789.         npr("3%-6.3f\r\n",ratio());
  790.       }
  791.       done=1;
  792.     }
  793.     break;
  794.     }
  795.   } while ((!done) && (!hangup));
  796. }
  797.