home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 September / PCO_0998.ISO / filesbbs / dos / sbbs_src.exe / SBBS / XFER_MID.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-02  |  27.5 KB  |  793 lines

  1. #line 1 "XFER_MID.C"
  2.  
  3. /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
  4.  
  5. #include "sbbs.h"
  6.  
  7. /****************************************************************************/
  8. /* This function is called when a file is unsuccessfully downloaded.        */
  9. /* It logs the tranfer time and checks for possible leech protocol use.     */
  10. /****************************************************************************/
  11. void notdownloaded(ulong size, time_t start, time_t end)
  12. {
  13.     char str[256],tmp2[256];
  14.  
  15. sprintf(str,"Estimated Time: %s  Transfer Time: %s"
  16.     ,sectostr(cur_cps ? size/cur_cps : 0,tmp)
  17.     ,sectostr((uint)end-start,tmp2));
  18. logline(nulstr,str);
  19. if(leech_pct && cur_cps                 /* leech detection */
  20.     && end-start>=leech_sec
  21.     && end-start>=(double)(size/cur_cps)*(double)leech_pct/100.0) {
  22.     sprintf(str,"Possible use of leech protocol (leech=%u  downloads=%u)"
  23.         ,useron.leech+1,useron.dls);
  24.     errorlog(str);
  25.     useron.leech=adjustuserrec(useron.number,U_LEECH,2,1); }
  26. }
  27.  
  28. /****************************************************************************/
  29. /* List detailed information about the files in 'filespec'. Prompts for     */
  30. /* action depending on 'mode.'                                              */
  31. /* Returns number of files matching filespec that were found                */
  32. /****************************************************************************/
  33. int listfileinfo(uint dirnum, char *filespec, char mode)
  34. {
  35.     uchar str[258],path[258],dirpath[256],done=0,ch,fname[13],ext[513];
  36.     uchar HUGE16 *ixbbuf,*usrxfrbuf=NULL,*p;
  37.     int i,j,found=0,file;
  38.     ulong l,m,usrcdt,usrxfrlen;
  39.     time_t start,end;
  40.     file_t f;
  41.  
  42. sprintf(str,"%sXFER.IXT",data_dir);
  43. if(mode==FI_USERXFER && flength(str)>0L) {
  44.     if((file=nopen(str,O_RDONLY))==-1) {
  45.         errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
  46.         return(0); }
  47.     usrxfrlen=filelength(file);
  48.     if((usrxfrbuf=MALLOC(usrxfrlen))==NULL) {
  49.         close(file);
  50.         errormsg(WHERE,ERR_ALLOC,str,usrxfrlen);
  51.         return(0); }
  52.     if(read(file,usrxfrbuf,usrxfrlen)!=usrxfrlen) {
  53.         close(file);
  54.         FREE(usrxfrbuf);
  55.         errormsg(WHERE,ERR_READ,str,usrxfrlen);
  56.         return(0); }
  57.     close(file); }
  58. sprintf(str,"%s%s.IXB",dir[dirnum]->data_dir,dir[dirnum]->code);
  59. if((file=nopen(str,O_RDONLY))==-1)
  60.     return(0);
  61. l=filelength(file);
  62. if(!l) {
  63.     close(file);
  64.     return(0); }
  65. if((ixbbuf=(char *)MALLOC(l))==NULL) {
  66.     close(file);
  67.     errormsg(WHERE,ERR_ALLOC,str,l);
  68.     return(0); }
  69. if(lread(file,ixbbuf,l)!=l) {
  70.     close(file);
  71.     errormsg(WHERE,ERR_READ,str,l);
  72.     FREE((char *)ixbbuf);
  73.     if(usrxfrbuf)
  74.         FREE(usrxfrbuf);
  75.     return(0); }
  76. close(file);
  77. sprintf(str,"%s%s.DAT",dir[dirnum]->data_dir,dir[dirnum]->code);
  78. if((file=nopen(str,O_RDONLY))==-1) {
  79.     errormsg(WHERE,ERR_READ,str,O_RDONLY);
  80.     FREE((char *)ixbbuf);
  81.     if(usrxfrbuf)
  82.         FREE(usrxfrbuf);
  83.     return(0); }
  84. close(file);
  85. m=0;
  86. while(online && !done && m<l) {
  87.     if(mode==FI_REMOVE && dir_op(dirnum))
  88.         action=NODE_SYSP;
  89.     else action=NODE_LFIL;
  90.     if(msgabort()) {
  91.         found=-1;
  92.         break; }
  93.     for(i=0;i<12 && m<l;i++)
  94.         if(i==8)
  95.             str[i]='.';
  96.         else
  97.             str[i]=ixbbuf[m++];     /* Turns FILENAMEEXT into FILENAME.EXT */
  98.     str[i]=0;
  99.     unpadfname(str,fname);
  100.     if(filespec[0] && !filematch(str,filespec)) {
  101.         m+=11;
  102.         continue; }
  103.     f.datoffset=ixbbuf[m]|((long)ixbbuf[m+1]<<8)|((long)ixbbuf[m+2]<<16);
  104.     f.dateuled=ixbbuf[m+3]|((long)ixbbuf[m+4]<<8)
  105.         |((long)ixbbuf[m+5]<<16)|((long)ixbbuf[m+6]<<24);
  106.     f.datedled=ixbbuf[m+7]|((long)ixbbuf[m+8]<<8)
  107.         |((long)ixbbuf[m+9]<<16)|((long)ixbbuf[m+10]<<24);
  108.     m+=11;
  109.     if(mode==FI_OLD && f.datedled>ns_time)
  110.         continue;
  111.     if((mode==FI_OLDUL || mode==FI_OLD) && f.dateuled>ns_time)
  112.         continue;
  113.     f.dir=curdirnum=dirnum;
  114.     strcpy(f.name,str);
  115.     f.size=0;
  116.     getfiledat(&f);
  117.     if(mode==FI_OFFLINE && f.size>=0)
  118.         continue;
  119.     if(f.altpath>0 && f.altpath<=altpaths)
  120.         strcpy(dirpath,altpath[f.altpath-1]);
  121.     else
  122.         strcpy(dirpath,dir[f.dir]->path);
  123.     if(mode==FI_CLOSE && !f.opencount)
  124.         continue;
  125.     if(mode==FI_USERXFER) {
  126.         for(p=usrxfrbuf;p<usrxfrbuf+usrxfrlen;p+=24) {
  127.             sprintf(str,"%17.17s",p);   /* %4.4u %12.12s */
  128.             if(!strcmp(str+5,f.name) && useron.number==atoi(str))
  129.                 break; }
  130.         if(p>=usrxfrbuf+usrxfrlen) /* file wasn't found */
  131.             continue; }
  132.     if((mode==FI_REMOVE) && (!dir_op(dirnum) && strcmpi(f.uler
  133.         ,useron.alias) && !(useron.exempt&FLAG('R'))))
  134.         continue;
  135.     found++;
  136.     if(mode==FI_INFO) {
  137.         if(!viewfile(f,1)) {
  138.             done=1;
  139.             found=-1; } }
  140.     else
  141.         fileinfo(f);
  142.     if(mode==FI_CLOSE) {
  143.         if(!noyes(text[CloseFileRecordQ])) {
  144.             f.opencount=0;
  145.             putfiledat(f); } }
  146.     else if(mode==FI_REMOVE || mode==FI_OLD || mode==FI_OLDUL
  147.         || mode==FI_OFFLINE) {
  148.         SYNC;
  149.         CRLF;
  150.         if(f.opencount) {
  151.             mnemonics(text[QuitOrNext]);
  152.             strcpy(str,"Q\r"); }
  153.         else if(dir_op(dirnum)) {
  154.             mnemonics(text[SysopRemoveFilePrompt]);
  155.             strcpy(str,"VEFMCQR\r"); }
  156.         else if(useron.exempt&FLAG('R')) {
  157.             mnemonics(text[RExemptRemoveFilePrompt]);
  158.             strcpy(str,"VEMQR\r"); }
  159.         else {
  160.             mnemonics(text[UserRemoveFilePrompt]);
  161.             strcpy(str,"VEQR\r"); }
  162.         switch(getkeys(str,0)) {
  163.             case 'V':
  164.                 viewfilecontents(f);
  165.                 CRLF;
  166.                 ASYNC;
  167.                 pause();
  168.                 m-=F_IXBSIZE;
  169.                 continue;
  170.             case 'E':   /* edit file information */
  171.                 if(dir_op(dirnum)) {
  172.                     bputs(text[EditFilename]);
  173.                     strcpy(str,fname);
  174.                     getstr(str,12,K_EDIT|K_AUTODEL|K_UPPER);
  175.                     if(strcmp(str,fname)) { /* rename */
  176.                         padfname(str,path);
  177.                         if(findfile(f.dir,path))
  178.                             bprintf(text[FileAlreadyThere],path);
  179.                         else {
  180.                             sprintf(path,"%s%s",dirpath,fname);
  181.                             sprintf(tmp,"%s%s",dirpath,str);
  182.                             if(rename(path,tmp))
  183.                                 bprintf(text[CouldntRenameFile],path,tmp);
  184.                             else {
  185.                                 bprintf(text[FileRenamed],path,tmp);
  186.                                 strcpy(fname,str);
  187.                                 removefiledat(f);
  188.                                 strcpy(f.name,padfname(str,tmp));
  189.                                 addfiledat(&f); } } } }
  190.                 bputs(text[EditDescription]);
  191.                 getstr(f.desc,LEN_FDESC,K_LINE|K_EDIT|K_AUTODEL);
  192.                 if(f.misc&FM_EXTDESC) {
  193.                     if(!noyes(text[DeleteExtDescriptionQ])) {
  194.                         remove(str);
  195.                         f.misc&=~FM_EXTDESC; } }
  196.                 if(!dir_op(dirnum)) {
  197.                     putfiledat(f);
  198.                     break; }
  199.                 bputs(text[EditUploader]);
  200.                 getstr(f.uler,LEN_ALIAS,K_UPRLWR|K_EDIT|K_AUTODEL);
  201.                 ultoa(f.cdt,str,10);
  202.                 bputs(text[EditCreditValue]);
  203.                 getstr(str,7,K_NUMBER|K_EDIT|K_AUTODEL);
  204.                 f.cdt=atol(str);
  205.                 itoa(f.timesdled,str,10);
  206.                 bputs(text[EditTimesDownloaded]);
  207.                 getstr(str,5,K_NUMBER|K_EDIT|K_AUTODEL);
  208.                 f.timesdled=atoi(str);
  209.                 if(f.opencount) {
  210.                     itoa(f.opencount,str,10);
  211.                     bputs(text[EditOpenCount]);
  212.                     getstr(str,3,K_NUMBER|K_EDIT|K_AUTODEL);
  213.                     f.opencount=atoi(str); }
  214.                 if(altpaths || f.altpath) {
  215.                     itoa(f.altpath,str,10);
  216.                     bputs(text[EditAltPath]);
  217.                     getstr(str,3,K_NUMBER|K_EDIT|K_AUTODEL);
  218.                     f.altpath=atoi(str);
  219.                     if(f.altpath>altpaths)
  220.                         f.altpath=0; }
  221.                 putfiledat(f);
  222.                 inputnstime(&f.dateuled);
  223.                 update_uldate(f);
  224.                 break;
  225.             case 'F':   /* delete file only */
  226.                 sprintf(str,"%s%s",dirpath,fname);
  227.                 if(!fexist(str))
  228.                     bputs(text[FileNotThere]);
  229.                 else {
  230.                     if(!noyes(text[AreYouSureQ])) {
  231.                         if(remove(str))
  232.                             bprintf(text[CouldntRemoveFile],str);
  233.                         else {
  234.                             sprintf(tmp,"Deleted %s",str);
  235.                             logline(nulstr,tmp); } } }
  236.                 break;
  237.             case 'R':   /* remove file from database */
  238.                 if(noyes(text[AreYouSureQ]))
  239.                     break;
  240.                 removefiledat(f);
  241.                 sprintf(str,"Removed %s from %s %s",f.name
  242.                     ,lib[dir[f.dir]->lib]->sname,dir[f.dir]->sname);
  243.                 logline("U-",str);
  244.                 sprintf(str,"%s%s",dirpath,fname);
  245.                 if(fexist(str)) {
  246.                     if(dir_op(dirnum)) {
  247.                         if(!noyes(text[DeleteFileQ])) {
  248.                             if(remove(str))
  249.                                 bprintf(text[CouldntRemoveFile],str);
  250.                             else {
  251.                                 sprintf(tmp,"Deleted %s",str);
  252.                                 logline(nulstr,tmp); } } }
  253.                     else if(remove(str))    /* always remove if not sysop */
  254.                         bprintf(text[CouldntRemoveFile],str); }
  255.                 if(dir_op(dirnum) || useron.exempt&FLAG('R')) {
  256.                     i=lib[dir[f.dir]->lib]->offline_dir;
  257.                     if(i!=dirnum && i!=(int)INVALID_DIR
  258.                         && !findfile(i,f.name)) {
  259.                         sprintf(str,text[AddToOfflineDirQ]
  260.                             ,fname,lib[dir[i]->lib]->sname,dir[i]->sname);
  261.                         if(yesno(str)) {
  262.                             getextdesc(f.dir,f.datoffset,ext);
  263.                             f.dir=i;
  264.                             addfiledat(&f);
  265.                             if(f.misc&FM_EXTDESC)
  266.                                 putextdesc(f.dir,f.datoffset,ext); } } }
  267.                 if(dir_op(dirnum) || strcmpi(f.uler,useron.alias)) {
  268.                     if(noyes(text[RemoveCreditsQ]))
  269. /* Fall through */      break; }
  270.             case 'C':   /* remove credits only */
  271.                 if((i=matchuser(f.uler))==0) {
  272.                     bputs(text[UnknownUser]);
  273.                     break; }
  274.                 if(dir_op(dirnum)) {
  275.                     usrcdt=(ulong)(f.cdt*(dir[f.dir]->up_pct/100.0));
  276.                     if(f.timesdled)     /* all downloads */
  277.                         usrcdt+=(ulong)((long)f.timesdled
  278.                             *f.cdt*(dir[f.dir]->dn_pct/100.0));
  279.                     ultoa(usrcdt,str,10);
  280.                     bputs(text[CreditsToRemove]);
  281.                     getstr(str,10,K_NUMBER|K_LINE|K_EDIT|K_AUTODEL);
  282.                     f.cdt=atol(str); }
  283.                 usrcdt=adjustuserrec(i,U_CDT,10,-f.cdt);
  284.                 if(i==useron.number)
  285.                     useron.cdt=usrcdt;
  286.                 sprintf(str,text[FileRemovedUserMsg]
  287.                     ,f.name,f.cdt ? ultoac(f.cdt,tmp) : text[No]);
  288.                 putsmsg(i,str);
  289.                 usrcdt=adjustuserrec(i,U_ULB,10,-f.size);
  290.                 if(i==useron.number)
  291.                     useron.ulb=usrcdt;
  292.                 usrcdt=adjustuserrec(i,U_ULS,5,-1);
  293.                 if(i==useron.number)
  294.                     useron.uls=usrcdt;
  295.                 break;
  296.             case 'M':   /* move the file to another dir */
  297.                 CRLF;
  298.                 for(i=0;i<usrlibs;i++)
  299.                     bprintf(text[MoveToLibLstFmt],i+1,lib[usrlib[i]]->lname);
  300.                 SYNC;
  301.                 bprintf(text[MoveToLibPrompt],dir[dirnum]->lib+1);
  302.                 if((i=getnum(usrlibs))==-1)
  303.                     continue;
  304.                 if(!i)
  305.                     i=dir[dirnum]->lib;
  306.                 else
  307.                     i--;
  308.                 CRLF;
  309.                 for(j=0;j<usrdirs[i];j++)
  310.                     bprintf(text[MoveToDirLstFmt]
  311.                         ,j+1,dir[usrdir[i][j]]->lname);
  312.                 SYNC;
  313.                 bprintf(text[MoveToDirPrompt],usrdirs[i]);
  314.                 if((j=getnum(usrdirs[i]))==-1)
  315.                     continue;
  316.                 if(!j)
  317.                     j=usrdirs[i]-1;
  318.                 else j--;
  319.                 CRLF;
  320.                 if(findfile(usrdir[i][j],f.name)) {
  321.                     bprintf(text[FileAlreadyThere],f.name);
  322.                     break; }
  323.                 getextdesc(f.dir,f.datoffset,ext);
  324.                 removefiledat(f);
  325.                 if(f.dir==upload_dir || f.dir==sysop_dir)
  326.                     f.dateuled=time(NULL);
  327.                 f.dir=usrdir[i][j];
  328.                 addfiledat(&f);
  329.                 bprintf(text[MovedFile],f.name
  330.                     ,lib[dir[f.dir]->lib]->sname,dir[f.dir]->sname);
  331.                 sprintf(str,"Moved %s to %s %s",f.name
  332.                     ,lib[dir[f.dir]->lib]->sname,dir[f.dir]->sname);
  333.                 logline(nulstr,str);
  334.                 if(!f.altpath) {    /* move actual file */
  335.                     sprintf(str,"%s%s",dir[dirnum]->path,fname);
  336.                     if(fexist(str)) {
  337.                         sprintf(path,"%s%s",dir[f.dir]->path,fname);
  338.                         mv(str,path,0); } }
  339.                 if(f.misc&FM_EXTDESC)
  340.                     putextdesc(f.dir,f.datoffset,ext);
  341.                 break;
  342.             case 'Q':   /* quit */
  343.                 found=-1;
  344.                 done=1;
  345.                 break; } }
  346.     else if(mode==FI_DOWNLOAD || mode==FI_USERXFER) {
  347.         sprintf(path,"%s%s",dirpath,fname);
  348.         if(f.size<1L) { /* getfiledat will set this to -1 if non-existant */
  349.             SYNC;       /* and 0 byte files shouldn't be d/led */
  350.             mnemonics(text[QuitOrNext]);
  351.             if(getkeys("\rQ",0)=='Q') {
  352.                 found=-1;
  353.                 break; }
  354.             continue; }
  355.         if(!(dir[f.dir]->misc&DIR_FREE) && !(useron.exempt&FLAG('D'))
  356.             && f.cdt>(useron.cdt+useron.freecdt)) {
  357.             SYNC;
  358.             bprintf(text[YouOnlyHaveNCredits]
  359.                 ,ultoac(useron.cdt+useron.freecdt,tmp));
  360.             mnemonics(text[QuitOrNext]);
  361.             if(getkeys("\rQ",0)=='Q') {
  362.                 found=-1;
  363.                 break; }
  364.             continue; }
  365.         if(!chk_ar(dir[f.dir]->dl_ar,useron)) {
  366.             SYNC;
  367.             bputs(text[CantDownloadFromDir]);
  368.             mnemonics(text[QuitOrNext]);
  369.             if(getkeys("\rQ",0)=='Q') {
  370.                 found=-1;
  371.                 break; }
  372.             continue; }
  373.         if(!(dir[f.dir]->misc&DIR_TFREE) && f.timetodl>timeleft && !dir_op(dirnum)
  374.             && !(useron.exempt&FLAG('T'))) {
  375.             SYNC;
  376.             bputs(text[NotEnoughTimeToDl]);
  377.             mnemonics(text[QuitOrNext]);
  378.             if(getkeys("\rQ",0)=='Q') {
  379.                 found=-1;
  380.                 break; }
  381.             continue; }
  382.         menu("DLPROT");
  383.         openfile(f);
  384.         SYNC;
  385.         mnemonics(text[ProtocolBatchQuitOrNext]);
  386.         strcpy(str,"BQ\r");
  387.         for(i=0;i<total_prots;i++)
  388.             if(prot[i]->dlcmd[0]
  389.                 && chk_ar(prot[i]->ar,useron)) {
  390.                 sprintf(tmp,"%c",prot[i]->mnemonic);
  391.                 strcat(str,tmp); }
  392. //          ungetkey(useron.prot);
  393.         ch=getkeys(str,0);
  394.         if(ch=='Q') {
  395.             found=-1;
  396.             done=1; }
  397.         else if(ch=='B') {
  398.             if(!addtobatdl(f)) {
  399.                 closefile(f);
  400.                 break; } }
  401.         else if(ch!=CR) {
  402.             for(i=0;i<total_prots;i++)
  403.                 if(prot[i]->dlcmd[0] && prot[i]->mnemonic==ch
  404.                     && chk_ar(prot[i]->ar,useron))
  405.                     break;
  406.             if(i<total_prots) {
  407.                 if(online==ON_LOCAL) {
  408.                     bputs(text[EnterPath]);
  409.                     if(getstr(path,60,K_UPPER|K_LINE)) {
  410.                         backslash(path);
  411.                         strcat(path,fname);
  412.                         sprintf(str,"%s%s",dirpath,fname);
  413.                         if(!mv(str,path,1))
  414.                             downloadfile(f);
  415.                         for(j=0;j<total_dlevents;j++)
  416.                             if(!stricmp(dlevent[j]->ext,f.name+9)
  417.                                 && chk_ar(dlevent[j]->ar,useron)) {
  418.                                 bputs(dlevent[j]->workstr);
  419.                                 external(cmdstr(dlevent[j]->cmd,path,nulstr
  420.                                     ,NULL)
  421.                                     ,EX_OUTL);
  422.                                 CRLF; }
  423.                             } }
  424.                 else {
  425.                     delfiles(temp_dir,"*.*");
  426.                     if(dir[f.dir]->seqdev) {
  427.                         lncntr=0;
  428.                         seqwait(dir[f.dir]->seqdev);
  429.                         bprintf(text[RetrievingFile],fname);
  430.                         sprintf(str,"%s%s",dirpath,fname);
  431.                         sprintf(path,"%s%s",temp_dir,fname);
  432.                         mv(str,path,1); /* copy the file to temp dir */
  433.                         getnodedat(node_num,&thisnode,1);
  434.                         thisnode.aux=0xf0;
  435.                         putnodedat(node_num,thisnode);
  436.                         CRLF; }
  437.                     for(j=0;j<total_dlevents;j++)
  438.                         if(!stricmp(dlevent[j]->ext,f.name+9)
  439.                             && chk_ar(dlevent[j]->ar,useron)) {
  440.                             bputs(dlevent[j]->workstr);
  441.                             external(cmdstr(dlevent[j]->cmd,path,nulstr,NULL)
  442.                                 ,EX_OUTL);
  443.                             CRLF; }
  444.                     getnodedat(node_num,&thisnode,1);
  445.                     action=NODE_DLNG;
  446.                     unixtodos(now+f.timetodl,&date,&curtime);
  447.                     thisnode.aux=(curtime.ti_hour*60)+curtime.ti_min;
  448.                     putnodedat(node_num,thisnode); /* calculate ETA */
  449.                     start=time(NULL);
  450.                     j=protocol(cmdstr(prot[i]->dlcmd,path,nulstr,NULL),0);
  451.                     end=time(NULL);
  452.                     if(dir[f.dir]->misc&DIR_TFREE)
  453.                         starttime+=end-start;
  454.                     if(prot[i]->misc&PROT_DSZLOG) {
  455.                         if(checkprotlog(f))
  456.                             downloadfile(f);
  457.                         else
  458.                             notdownloaded(f.size,start,end); }
  459.                     else {
  460.                         if(!j)
  461.                             downloadfile(f);
  462.                         else {
  463.                             bprintf(text[FileNotSent],f.name);
  464.                             notdownloaded(f.size,start,end); } }
  465.                     delfiles(temp_dir,"*.*");
  466.                     autohangup(); } } }
  467.         closefile(f); }
  468.     if(filespec[0] && !strchr(filespec,'*') && !strchr(filespec,'?')) break; }
  469. FREE((char *)ixbbuf);
  470. if(usrxfrbuf)
  471.     FREE(usrxfrbuf);
  472. return(found);
  473. }
  474.  
  475.  
  476. /****************************************************************************/
  477. /* Checks  directory data file for 'filename' (must be padded). If found,   */
  478. /* it returns the 1, else returns 0.                                        */
  479. /* Called from upload and bulkupload                                        */
  480. /****************************************************************************/
  481. char findfile(uint dirnum, char *filename)
  482. {
  483.     char str[256],c,fname[13],HUGE16 *ixbbuf;
  484.     int file;
  485.     ulong length,l;
  486.  
  487. sprintf(fname,"%.12s",filename);
  488. strupr(fname);
  489. for(c=8;c<12;c++)   /* Turn FILENAME.EXT into FILENAMEEXT */
  490.     fname[c]=fname[c+1];
  491. sprintf(str,"%s%s.IXB",dir[dirnum]->data_dir,dir[dirnum]->code);
  492. if((file=nopen(str,O_RDONLY))==-1) return(0);
  493. length=filelength(file);
  494. if(!length) {
  495.     close(file);
  496.     return(0); }
  497. if((ixbbuf=(char *)MALLOC(length))==NULL) {
  498.     close(file);
  499.     errormsg(WHERE,ERR_ALLOC,str,length);
  500.     return(0); }
  501. if(lread(file,ixbbuf,length)!=length) {
  502.     close(file);
  503.     errormsg(WHERE,ERR_READ,str,length);
  504.     FREE((char *)ixbbuf);
  505.     return(0); }
  506. close(file);
  507. for(l=0;l<length;l+=F_IXBSIZE) {
  508.     for(c=0;c<11;c++)
  509.         if(fname[c]!=toupper(ixbbuf[l+c])) break;
  510.     if(c==11) break; }
  511. FREE((char *)ixbbuf);
  512. if(l!=length)
  513.     return(1);
  514. return(0);
  515. }
  516.  
  517. /****************************************************************************/
  518. /* Prints one file's information on a single line to a file 'file'          */
  519. /****************************************************************************/
  520. void listfiletofile(char *fname, char HUGE16 *buf, uint dirnum, int file)
  521. {
  522.     char str[256],exist=1;
  523.     uchar alt;
  524.     ulong cdt;
  525.  
  526. strcpy(str,fname);
  527. if(buf[F_MISC]!=ETX && (buf[F_MISC]-SP)&FM_EXTDESC)
  528.     strcat(str,"+");
  529. else
  530.     strcat(str," ");
  531. write(file,str,13);
  532. getrec((char *)buf,F_ALTPATH,2,str);
  533. alt=(uchar)ahtoul(str);
  534. sprintf(str,"%s%s",alt>0 && alt<=altpaths ? altpath[alt-1]
  535.     : dir[dirnum]->path,unpadfname(fname,tmp));
  536. if(dir[dirnum]->misc&DIR_FCHK && !fexist(str))
  537.     exist=0;
  538. getrec((char *)buf,F_CDT,LEN_FCDT,str);
  539. cdt=atol(str);
  540. if(!cdt)
  541.     strcpy(str,"   FREE");
  542. else
  543.     sprintf(str,"%7lu",cdt);
  544. if(exist)
  545.     strcat(str," ");
  546. else
  547.     strcat(str,"-");
  548. write(file,str,8);
  549. getrec((char *)buf,F_DESC,LEN_FDESC,str);
  550. write(file,str,strlen(str));
  551. write(file,crlf,2);
  552. }
  553.  
  554.  
  555.  
  556. /****************************************************************************/
  557. /* Handles start and stop routines for transfer protocols                   */
  558. /****************************************************************************/
  559. int protocol(char *cmdline, int cd)
  560. {
  561.     char tmp[128];
  562.     int i;
  563.  
  564. sprintf(tmp,"%sPROTOCOL.LOG",node_dir);
  565. remove(tmp);                            /* Deletes the protocol log */
  566. if(useron.misc&AUTOHANG)
  567.     autohang=1;
  568. else
  569.     autohang=yesno(text[HangUpAfterXferQ]);
  570. if(sys_status&SS_ABORT) {                /* if ctrl-c */
  571.     autohang=0;
  572.     return(-1); }
  573. bputs(text[StartXferNow]);
  574. RIOSYNC(0);
  575. lprintf("%s\r\n",cmdline);
  576. if(cd) {
  577.     if(temp_dir[1]==':')    /* fix for DSZ */
  578.         setdisk(toupper(temp_dir[0])-'A');
  579.     strcpy(tmp,temp_dir);
  580.     tmp[strlen(tmp)-1]=0;    /* take off '\' */
  581.     if(chdir(tmp))
  582.         errormsg(WHERE,ERR_CHDIR,tmp,0); }
  583. i=external(cmdline,EX_OUTL);    /* EX_CC removed because of error level prob */
  584. if(online==ON_REMOTE)
  585.     rioctl(IOFB);
  586. CRLF;
  587. if(autohang) sys_status|=SS_PAUSEOFF;    /* Pause off after download */
  588. return(i);
  589. }
  590.  
  591. /****************************************************************************/
  592. /* Invokes the timed auto-hangup after transfer routine                     */
  593. /****************************************************************************/
  594. void autohangup()
  595. {
  596.     char a,c,k;
  597.  
  598. SYNC;
  599. sys_status&=~SS_PAUSEOFF;        /* turn pause back on */
  600. rioctl(IOFI);
  601. if(!autohang) return;
  602. lncntr=0;
  603. bputs(text[Disconnecting]);
  604. attr(GREEN);
  605. outchar('[');
  606. for(c=9,a=0;c>-1 && online && !a;c--) {
  607.     checkline();
  608.     attr(LIGHTGRAY|HIGH);
  609.     bputs(itoa(c,tmp,10));
  610.     attr(GREEN);
  611.     outchar(']');
  612.     while((k=inkey(0))!=0 && online) {
  613.         if(toupper(k)=='H') {
  614.             c=0;
  615.             break; }
  616.         if(toupper(k)=='A') {
  617.             a=1;
  618.             break; } }
  619.     mswait(DELAY_AUTOHG);
  620.     if(!a) {
  621.         outchar(BS);
  622.         outchar(BS); } }
  623. if(c==-1) {
  624.     bputs(text[Disconnected]);
  625.     hangup(); }
  626. else
  627.     CRLF;
  628. }
  629.  
  630. /****************************************************************************/
  631. /* Checks dsz compatible log file for errors in transfer                    */
  632. /* Returns 1 if the file in the struct file_t was successfuly transfered    */
  633. /****************************************************************************/
  634. char checkprotlog(file_t f)
  635. {
  636.     char str[256],size[128];
  637.     int file;
  638.     FILE *stream;
  639.  
  640. sprintf(str,"%sPROTOCOL.LOG",node_dir);
  641. if((stream=fnopen(&file,str,O_RDONLY))==NULL) {
  642.     bprintf(text[FileNotSent],f.name);
  643.     if(f.dir<total_dirs)
  644.         sprintf(str,"Attempted to download %s (%s) from %s %s"
  645.             ,f.name,ultoac(f.size,size)
  646.             ,lib[dir[f.dir]->lib]->sname,dir[f.dir]->sname);
  647.     else if(f.dir==total_dirs)
  648.         strcpy(str,"Attempted to download QWK packet");
  649.     else if(f.dir==total_dirs+1)
  650.         sprintf(str,"Attempted to download attached file: %s",f.name);
  651.     logline("D!",str);
  652.     return(0); }
  653. unpadfname(f.name,tmp);
  654. if(tmp[strlen(tmp)-1]=='.')     /* DSZ log uses FILE instead of FILE. */
  655.     tmp[strlen(tmp)-1]=0;       /* when there isn't an extension.     */
  656. while(!ferror(stream)) {
  657.     if(!fgets(str,256,stream))
  658.         break;
  659.     if(str[strlen(str)-2]==CR)
  660.         str[strlen(str)-2]=0;       /* chop off CRLF */
  661.     strupr(str);
  662.     if(strstr(str,tmp)) {   /* Only check for name, Bimodem doesn't put path */
  663.         logline(nulstr,str);
  664.         if(str[0]=='E' || str[0]=='L' || (str[6]==SP && str[7]=='0'))
  665.             break;          /* E for Error or L for Lost Carrier */
  666.         fclose(stream);     /* or only sent 0 bytes! */
  667.         return(1); } }
  668. fclose(stream);
  669. bprintf(text[FileNotSent],f.name);
  670. if(f.dir<total_dirs)
  671.     sprintf(str,"Attempted to download %s (%s) from %s %s",f.name
  672.         ,ultoac(f.size,tmp),lib[dir[f.dir]->lib]->sname,dir[f.dir]->sname);
  673. else
  674.     strcpy(str,"Attempted to download QWK packet");
  675. logline("D!",str);
  676. return(0);
  677. }
  678.  
  679. /*****************************************************************************/
  680. /* View viewable file types from dir 'dirnum'                                */
  681. /* 'fspec' must be padded                                                    */
  682. /*****************************************************************************/
  683. void viewfiles(uint dirnum, char *fspec)
  684. {
  685.     char viewcmd[256];
  686.     int i;
  687.  
  688. curdirnum=dirnum;    /* for ARS */
  689. sprintf(viewcmd,"%s%s",dir[dirnum]->path,fspec);
  690. if(!fexist(viewcmd)) {
  691.     bputs(text[FileNotFound]);
  692.     return; }
  693. padfname(fspec,tmp);
  694. truncsp(tmp);
  695. for(i=0;i<total_fviews;i++)
  696.     if(!strcmp(tmp+9,fview[i]->ext) && chk_ar(fview[i]->ar,useron)) {
  697.         strcpy(viewcmd,fview[i]->cmd);
  698.         break; }
  699. if(i==total_fviews) {
  700.     bprintf(text[NonviewableFile],tmp+9);
  701.     return; }
  702. sprintf(tmp,"%s%s",dir[dirnum]->path,fspec);
  703. if((i=external(cmdstr(viewcmd,tmp,tmp,NULL),EX_OUTL|EX_OUTR|EX_INR|EX_CC))!=0)
  704.     errormsg(WHERE,ERR_EXEC,viewcmd,i);    /* must of EX_CC to ^C */
  705. }
  706.  
  707. /****************************************************************************/
  708. /* Compares filenames for ascending name sort                                */
  709. /****************************************************************************/
  710. int fnamecmp_a(char **str1, char **str2)
  711. {
  712. return(strncmp(*str1,*str2,11));
  713. }
  714.  
  715. /****************************************************************************/
  716. /* Compares filenames for descending name sort                                */
  717. /****************************************************************************/
  718. int fnamecmp_d(char **str1, char **str2)
  719. {
  720. return(strncmp(*str2,*str1,11));
  721. }
  722.  
  723. /****************************************************************************/
  724. /* Compares file upload dates for ascending date sort                        */
  725. /****************************************************************************/
  726. int fdatecmp_a(uchar **buf1, uchar **buf2)
  727. {
  728.     time_t date1,date2;
  729.  
  730. date1=((*buf1)[14]|((long)(*buf1)[15]<<8)|((long)(*buf1)[16]<<16)
  731.     |((long)(*buf1)[17]<<24));
  732. date2=((*buf2)[14]|((long)(*buf2)[15]<<8)|((long)(*buf2)[16]<<16)
  733.     |((long)(*buf2)[17]<<24));
  734. if(date1>date2)    return(1);
  735. if(date1<date2)    return(-1);
  736. return(0);
  737. }
  738.  
  739. /****************************************************************************/
  740. /* Compares file upload dates for descending date sort                        */
  741. /****************************************************************************/
  742. int fdatecmp_d(uchar **buf1, uchar **buf2)
  743. {
  744.     time_t date1,date2;
  745.  
  746. date1=((*buf1)[14]|((long)(*buf1)[15]<<8)|((long)(*buf1)[16]<<16)
  747.     |((long)(*buf1)[17]<<24));
  748. date2=((*buf2)[14]|((long)(*buf2)[15]<<8)|((long)(*buf2)[16]<<16)
  749.     |((long)(*buf2)[17]<<24));
  750. if(date1>date2)    return(-1);
  751. if(date1<date2)    return(1);
  752. return(0);
  753. }
  754.  
  755. /************************************************************************/
  756. /* Wait (for a limited period of time) for sequential dev to become     */
  757. /* available for file retrieval                                         */
  758. /************************************************************************/
  759. void seqwait(uint devnum)
  760. {
  761.     char loop=0;
  762.     int i;
  763.     time_t start;
  764.     node_t node;
  765.  
  766.  
  767. if(!devnum)
  768.     return;
  769. for(start=now=time(NULL);online && now-start<90;now=time(NULL)) {
  770.     if(msgabort())                /* max wait ^^^^ sec */
  771.         break;
  772.     getnodedat(node_num,&thisnode,1);    /* open and lock this record */
  773.     for(i=1;i<=sys_nodes;i++) {
  774.         if(i==node_num) continue;
  775.         getnodedat(i,&node,1);
  776.         if((node.status==NODE_INUSE || node.status==NODE_QUIET)
  777.             && node.action==NODE_RFSD && node.aux==devnum) {
  778.             putnodedat(i,node);
  779.             break; }
  780.         putnodedat(i,node); }
  781.     if(i>sys_nodes) {
  782.         thisnode.action=NODE_RFSD;
  783.         thisnode.aux=devnum;
  784.         putnodedat(node_num,thisnode);    /* write devnum, unlock, and ret */
  785.         return; }
  786.     putnodedat(node_num,thisnode);
  787.     if(!loop)
  788.         bprintf(text[WaitingForDeviceN],devnum);
  789.     loop=1;
  790.     mswait(100); }
  791.  
  792. }
  793.