|
|
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.