|
|
1.1 root 1: /* listfile.cpp */
2:
3: /* Synchronet file database listing functions */
4:
5: /* $Id: listfile.cpp,v 1.45 2006/08/03 02:45:09 rswindell Exp $ */
6:
7: /****************************************************************************
8: * @format.tab-size 4 (Plain Text/Source Code File Header) *
9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
10: * *
11: * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html *
12: * *
13: * This program is free software; you can redistribute it and/or *
14: * modify it under the terms of the GNU General Public License *
15: * as published by the Free Software Foundation; either version 2 *
16: * of the License, or (at your option) any later version. *
17: * See the GNU General Public License for more details: gpl.txt or *
18: * http://www.fsf.org/copyleft/gpl.html *
19: * *
20: * Anonymous FTP access to the most recent released source is available at *
21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
22: * *
23: * Anonymous CVS access to the development source and modification history *
24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: *
25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
26: * (just hit return, no password is necessary) *
27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
28: * *
29: * For Synchronet coding style and modification guidelines, see *
30: * http://www.synchro.net/source.html *
31: * *
32: * You are encouraged to submit any modifications (preferably in Unix diff *
33: * format) via e-mail to [email protected] *
34: * *
35: * Note: If this box doesn't appear square, then you need to fix your tabs. *
36: ****************************************************************************/
37:
38: #include "sbbs.h"
39:
40: #define BF_MAX 26 /* Batch Flag max: A-Z */
41:
42: int extdesclines(char *str);
43:
44: /*****************************************************************************/
45: /* List files in directory 'dir' that match 'filespec'. Filespec must be */
46: /* padded. ex: FILE* .EXT, not FILE*.EXT. 'mode' determines other critiria */
47: /* the files must meet before they'll be listed. 'mode' bit FL_NOHDR doesn't */
48: /* list the directory header. */
49: /* Returns -1 if the listing was aborted, otherwise total files listed */
50: /*****************************************************************************/
51: int sbbs_t::listfiles(uint dirnum, char *filespec, int tofile, long mode)
52: {
53: char str[256],hdr[256],c,d,letter='A',*p,*datbuf,ext[513];
54: char tmp[512];
55: uchar* ixbbuf;
56: uchar flagprompt=0;
57: uint i,j;
58: int file,found=0,lastbat=0,disp;
59: long l,m=0,n,anchor=0,next,datbuflen;
60: file_t f,bf[26]; /* bf is batch flagged files */
61:
62: if(mode&FL_ULTIME) {
63: last_ns_time=now;
64: sprintf(str,"%s%s.dab",cfg.dir[dirnum]->data_dir,cfg.dir[dirnum]->code);
65: if((file=nopen(str,O_RDONLY))!=-1) {
66: read(file,&l,4);
67: close(file);
68: if(ns_time>(time_t)l)
69: return(0); } }
70: sprintf(str,"%s%s.ixb",cfg.dir[dirnum]->data_dir,cfg.dir[dirnum]->code);
71: if((file=nopen(str,O_RDONLY))==-1)
72: return(0);
73: l=filelength(file);
74: if(!l) {
75: close(file);
76: return(0); }
77: if((ixbbuf=(uchar *)malloc(l))==NULL) {
78: close(file);
79: errormsg(WHERE,ERR_ALLOC,str,l);
80: return(0); }
81: if(lread(file,ixbbuf,l)!=l) {
82: close(file);
83: errormsg(WHERE,ERR_READ,str,l);
84: free((char *)ixbbuf);
85: return(0); }
86: close(file);
87: sprintf(str,"%s%s.dat",cfg.dir[dirnum]->data_dir,cfg.dir[dirnum]->code);
88: if((file=nopen(str,O_RDONLY))==-1) {
89: errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
90: free((char *)ixbbuf);
91: return(0); }
92: datbuflen=filelength(file);
93: if((datbuf=(char *)malloc(datbuflen))==NULL) {
94: close(file);
95: errormsg(WHERE,ERR_ALLOC,str,datbuflen);
96: free((char *)ixbbuf);
97: return(0); }
98: if(lread(file,datbuf,datbuflen)!=datbuflen) {
99: close(file);
100: errormsg(WHERE,ERR_READ,str,datbuflen);
101: free((char *)datbuf);
102: free((char *)ixbbuf);
103: return(0); }
104: close(file);
105: if(!tofile) {
106: action=NODE_LFIL;
107: getnodedat(cfg.node_num,&thisnode,0);
108: if(thisnode.action!=NODE_LFIL) { /* was a sync */
109: if(getnodedat(cfg.node_num,&thisnode,true)==0) {
110: thisnode.action=NODE_LFIL;
111: putnodedat(cfg.node_num,&thisnode);
112: }
113: }
114: }
115:
116: while(online && found<MAX_FILES) {
117: if(found<0)
118: found=0;
119: if(m>=l || flagprompt) { /* End of list */
120: if(useron.misc&BATCHFLAG && !tofile && found && found!=lastbat
121: && !(mode&(FL_EXFIND|FL_VIEW))) {
122: flagprompt=0;
123: lncntr=0;
124: if((i=batchflagprompt(dirnum,bf,letter-'A',l/F_IXBSIZE))==2) {
125: m=anchor;
126: found-=letter-'A';
127: letter='A'; }
128: else if(i==3) {
129: if((long)anchor-((letter-'A')*F_IXBSIZE)<0) {
130: m=0;
131: found=0; }
132: else {
133: m=anchor-((letter-'A')*F_IXBSIZE);
134: found-=letter-'A'; }
135: letter='A'; }
136: else if((int)i==-1) {
137: free((char *)ixbbuf);
138: free((char *)datbuf);
139: return(-1); }
140: else
141: break;
142: getnodedat(cfg.node_num,&thisnode,0);
143: nodesync(); }
144: else
145: break; }
146:
147: if(letter>'Z')
148: letter='A';
149: if(letter=='A')
150: anchor=m;
151:
152: if(msgabort()) { /* used to be !tofile && msgabort() */
153: free((char *)ixbbuf);
154: free((char *)datbuf);
155: return(-1); }
156: for(j=0;j<12 && m<l;j++)
157: if(j==8)
158: str[j]=ixbbuf[m]>' ' ? '.' : ' ';
159: else
160: str[j]=ixbbuf[m++]; /* Turns FILENAMEEXT into FILENAME.EXT */
161: str[j]=0;
162: if(!(mode&(FL_FINDDESC|FL_EXFIND)) && filespec[0]
163: && !filematch(str,filespec)) {
164: m+=11;
165: continue; }
166: n=ixbbuf[m]|((long)ixbbuf[m+1]<<8)|((long)ixbbuf[m+2]<<16);
167: if(n>=datbuflen) { /* out of bounds */
168: m+=11;
169: continue; }
170: if(mode&(FL_FINDDESC|FL_EXFIND)) {
171: getrec((char *)&datbuf[n],F_DESC,LEN_FDESC,tmp);
172: strupr(tmp);
173: p=strstr(tmp,filespec);
174: if(!(mode&FL_EXFIND) && p==NULL) {
175: m+=11;
176: continue; }
177: getrec((char *)&datbuf[n],F_MISC,1,tmp);
178: j=tmp[0]; /* misc bits */
179: if(j) j-=' ';
180: if(mode&FL_EXFIND && j&FM_EXTDESC) { /* search extended description */
181: getextdesc(&cfg,dirnum,n,ext);
182: strupr(ext);
183: if(!strstr(ext,filespec) && !p) { /* not in description or */
184: m+=11; /* extended description */
185: continue; } }
186: else if(!p) { /* no extended description and not in desc */
187: m+=11;
188: continue; } }
189: if(mode&FL_ULTIME) {
190: if(ns_time>(ixbbuf[m+3]|((long)ixbbuf[m+4]<<8)|((long)ixbbuf[m+5]<<16)
191: |((long)ixbbuf[m+6]<<24))) {
192: m+=11;
193: continue; } }
194: if(useron.misc&BATCHFLAG && letter=='A' && found && !tofile
195: && !(mode&(FL_EXFIND|FL_VIEW))
196: && (!mode || !(useron.misc&EXPERT)))
197: bputs(text[FileListBatchCommands]);
198: m+=11;
199: if(!found && !(mode&(FL_EXFIND|FL_VIEW))) {
200: for(i=0;i<usrlibs;i++)
201: if(usrlib[i]==cfg.dir[dirnum]->lib)
202: break;
203: for(j=0;j<usrdirs[i];j++)
204: if(usrdir[i][j]==dirnum)
205: break; /* big header */
206: if((!mode || !(useron.misc&EXPERT)) && !tofile && (!filespec[0]
207: || (strchr(filespec,'*') || strchr(filespec,'?')))) {
208: sprintf(hdr,"%s%s.hdr",cfg.dir[dirnum]->data_dir,cfg.dir[dirnum]->code);
209: if(fexistcase(hdr))
210: printfile(hdr,0); /* Use DATA\DIRS\<CODE>.HDR */
211: else {
212: if(useron.misc&BATCHFLAG)
213: bputs(text[FileListBatchCommands]);
214: else {
215: CLS;
216: d=strlen(cfg.lib[usrlib[i]]->lname)>strlen(cfg.dir[dirnum]->lname) ?
217: strlen(cfg.lib[usrlib[i]]->lname)+17
218: : strlen(cfg.dir[dirnum]->lname)+17;
219: if(i>8 || j>8) d++;
220: attr(cfg.color[clr_filelsthdrbox]);
221: bputs("��"); /* use to start with \r\n */
222: for(c=0;c<d;c++)
223: outchar('�');
224: bputs("�\r\n� ");
225: sprintf(hdr,text[BoxHdrLib],i+1,cfg.lib[usrlib[i]]->lname);
226: bputs(hdr);
227: for(c=bstrlen(hdr);c<d;c++)
228: outchar(' ');
229: bputs("�\r\n� ");
230: sprintf(hdr,text[BoxHdrDir],j+1,cfg.dir[dirnum]->lname);
231: bputs(hdr);
232: for(c=bstrlen(hdr);c<d;c++)
233: outchar(' ');
234: bputs("�\r\n� ");
235: sprintf(hdr,text[BoxHdrFiles],l/F_IXBSIZE);
236: bputs(hdr);
237: for(c=bstrlen(hdr);c<d;c++)
238: outchar(' ');
239: bputs("�\r\n��");
240: for(c=0;c<d;c++)
241: outchar('�');
242: bputs("�\r\n"); } } }
243: else { /* short header */
244: if(tofile) {
245: sprintf(hdr,"(%u) %s ",i+1,cfg.lib[usrlib[i]]->sname);
246: write(tofile,crlf,2);
247: write(tofile,hdr,strlen(hdr)); }
248: else {
249: sprintf(hdr,text[ShortHdrLib],i+1,cfg.lib[usrlib[i]]->sname);
250: bputs("\r\1>\r\n");
251: bputs(hdr); }
252: c=bstrlen(hdr);
253: if(tofile) {
254: sprintf(hdr,"(%u) %s",j+1,cfg.dir[dirnum]->lname);
255: write(tofile,hdr,strlen(hdr)); }
256: else {
257: sprintf(hdr,text[ShortHdrDir],j+1,cfg.dir[dirnum]->lname);
258: bputs(hdr); }
259: c+=bstrlen(hdr);
260: if(tofile) {
261: write(tofile,crlf,2);
262: sprintf(hdr,"%*s",c,nulstr);
263: memset(hdr,'�',c);
264: strcat(hdr,crlf);
265: write(tofile,hdr,strlen(hdr)); }
266: else {
267: CRLF;
268: attr(cfg.color[clr_filelstline]);
269: while(c--)
270: outchar('�');
271: CRLF; } } }
272: next=m;
273: disp=1;
274: if(mode&(FL_EXFIND|FL_VIEW)) {
275: f.dir=dirnum;
276: strcpy(f.name,str);
277: m-=11;
278: f.datoffset=n;
279: f.dateuled=ixbbuf[m+3]|((long)ixbbuf[m+4]<<8)
280: |((long)ixbbuf[m+5]<<16)|((long)ixbbuf[m+6]<<24);
281: f.datedled=ixbbuf[m+7]|((long)ixbbuf[m+8]<<8)
282: |((long)ixbbuf[m+9]<<16)|((long)ixbbuf[m+10]<<24);
283: m+=11;
284: f.size=0;
285: getfiledat(&cfg,&f);
286: if(!found)
287: bputs("\r\1>");
288: if(mode&FL_EXFIND) {
289: if(!viewfile(&f,1)) {
290: free((char *)ixbbuf);
291: free((char *)datbuf);
292: return(-1); } }
293: else {
294: if(!viewfile(&f,0)) {
295: free((char *)ixbbuf);
296: free((char *)datbuf);
297: return(-1); } } }
298:
299: else if(tofile)
300: listfiletofile(str,&datbuf[n],dirnum,tofile);
301: else if(mode&FL_FINDDESC)
302: disp=listfile(str,&datbuf[n],dirnum,filespec,letter,n);
303: else
304: disp=listfile(str,&datbuf[n],dirnum,nulstr,letter,n);
305: if(!disp && letter>'A') {
306: next=m-F_IXBSIZE;
307: letter--; }
308: else {
309: disp=1;
310: found++; }
311: if(sys_status&SS_ABORT) {
312: free((char *)ixbbuf);
313: free((char *)datbuf);
314: return(-1); }
315: if(mode&(FL_EXFIND|FL_VIEW))
316: continue;
317: if(useron.misc&BATCHFLAG && !tofile) {
318: if(disp) {
319: strcpy(bf[letter-'A'].name,str);
320: m-=11;
321: bf[letter-'A'].datoffset=n;
322: bf[letter-'A'].dateuled=ixbbuf[m+3]|((long)ixbbuf[m+4]<<8)
323: |((long)ixbbuf[m+5]<<16)|((long)ixbbuf[m+6]<<24);
324: bf[letter-'A'].datedled=ixbbuf[m+7]|((long)ixbbuf[m+8]<<8)
325: |((long)ixbbuf[m+9]<<16)|((long)ixbbuf[m+10]<<24); }
326: m+=11;
327: if(flagprompt || letter=='Z' || !disp ||
328: (filespec[0] && !strchr(filespec,'*') && !strchr(filespec,'?')
329: && !(mode&FL_FINDDESC))
330: || (useron.misc&BATCHFLAG && !tofile && lncntr>=rows-2)
331: ) {
332: flagprompt=0;
333: lncntr=0;
334: lastbat=found;
335: if((int)(i=batchflagprompt(dirnum,bf,letter-'A'+1,l/F_IXBSIZE))<1) {
336: free((char *)ixbbuf);
337: free((char *)datbuf);
338: if((int)i==-1)
339: return(-1);
340: else
341: return(found); }
342: if(i==2) {
343: next=anchor;
344: found-=(letter-'A')+1; }
345: else if(i==3) {
346: if((long)anchor-((letter-'A'+1)*F_IXBSIZE)<0) {
347: next=0;
348: found=0; }
349: else {
350: next=anchor-((letter-'A'+1)*F_IXBSIZE);
351: found-=letter-'A'+1; } }
352: getnodedat(cfg.node_num,&thisnode,0);
353: nodesync();
354: letter='A'; }
355: else letter++; }
356: if(useron.misc&BATCHFLAG && !tofile
357: && lncntr>=rows-2) {
358: lncntr=0; /* defeat pause() */
359: flagprompt=1; }
360: m=next;
361: if(mode&FL_FINDDESC) continue;
362: if(filespec[0] && !strchr(filespec,'*') && !strchr(filespec,'?') && m)
363: break; }
364:
365: free((char *)ixbbuf);
366: free((char *)datbuf);
367: return(found);
368: }
369:
370: /****************************************************************************/
371: /* Prints one file's information on a single line */
372: /* Return 1 if displayed, 0 otherwise */
373: /****************************************************************************/
374: bool sbbs_t::listfile(char *fname, char *buf, uint dirnum
375: , char *search, char letter, ulong datoffset)
376: {
377: char str[256],ext[513]="",*ptr,*cr,*lf,exist=1;
378: char path[MAX_PATH+1];
379: char tmp[512];
380: uchar alt;
381: int i,j;
382: ulong cdt;
383:
384: if(buf[F_MISC]!=ETX && (buf[F_MISC]-' ')&FM_EXTDESC && useron.misc&EXTDESC) {
385: getextdesc(&cfg,dirnum,datoffset,ext);
386: if(useron.misc&BATCHFLAG && lncntr+extdesclines(ext)>=rows-2 && letter!='A')
387: return(false); }
388:
389: attr(cfg.color[clr_filename]);
390: bputs(fname);
391:
392: getrec((char *)buf,F_ALTPATH,2,str);
393: alt=(uchar)ahtoul(str);
394: sprintf(path,"%s%s",alt>0 && alt<=cfg.altpaths ? cfg.altpath[alt-1]:cfg.dir[dirnum]->path
395: ,unpadfname(fname,tmp));
396:
397: if(buf[F_MISC]!=ETX && (buf[F_MISC]-' ')&FM_EXTDESC) {
398: if(!(useron.misc&EXTDESC))
399: outchar('+');
400: else
401: outchar(' '); }
402: else
403: outchar(' ');
404: if(useron.misc&BATCHFLAG) {
405: attr(cfg.color[clr_filedesc]);
406: bprintf("%c",letter); }
407: if(cfg.dir[dirnum]->misc&DIR_FCHK && !fexistcase(path)) {
408: exist=0;
409: attr(cfg.color[clr_err]); }
410: else
411: attr(cfg.color[clr_filecdt]);
412: getrec((char *)buf,F_CDT,LEN_FCDT,str);
413: cdt=atol(str);
414: if(useron.misc&BATCHFLAG) {
415: if(!cdt) {
416: attr(curatr^(HIGH|BLINK));
417: bputs(" FREE"); }
418: else {
419: if(cdt<1024) /* 1k is smallest size */
420: cdt=1024;
421: if(cdt>(99999*1024))
422: bprintf("%5luM",cdt/(1024*1024));
423: else
424: bprintf("%5luk",cdt/1024L); } }
425: else {
426: if(!cdt) { /* FREE file */
427: attr(curatr^(HIGH|BLINK));
428: bputs(" FREE"); }
429: else if(cdt>9999999L)
430: bprintf("%6luk",cdt/1024L);
431: else
432: bprintf("%7lu",cdt); }
433: if(exist)
434: outchar(' ');
435: else
436: outchar('-');
437: getrec((char *)buf,F_DESC,LEN_FDESC,str);
438: attr(cfg.color[clr_filedesc]);
439:
440: #ifdef _WIN32
441:
442: if(exist && !(cfg.file_misc&FM_NO_LFN)) {
443: fexistcase(path); /* Get real (long?) filename */
444: ptr=getfname(path);
445: if(stricmp(ptr,tmp) && stricmp(ptr,str))
446: bprintf("%.*s\r\n%21s",LEN_FDESC,ptr,"");
447: }
448:
449: #endif
450:
451: if(!ext[0]) {
452: if(search[0]) { /* high-light string in string */
453: strcpy(tmp,str);
454: strupr(tmp);
455: ptr=strstr(tmp,search);
456: i=strlen(search);
457: j=ptr-tmp;
458: bprintf("%.*s",j,str);
459: attr(cfg.color[clr_filedesc]^HIGH);
460: bprintf("%.*s",i,str+j);
461: attr(cfg.color[clr_filedesc]);
462: bprintf("%.*s",strlen(str)-(j+i),str+j+i); }
463: else
464: bputs(str);
465: CRLF; }
466: ptr=ext;
467: while(*ptr && ptr<ext+512 && !msgabort()) {
468: cr=strchr(ptr,CR);
469: lf=strchr(ptr,LF);
470: if(lf && (lf<cr || !cr)) cr=lf;
471: if(cr>ptr+LEN_FDESC)
472: cr=ptr+LEN_FDESC;
473: else if(cr)
474: *cr=0;
475: sprintf(str,"%.*s\r\n",LEN_FDESC,ptr);
476: putmsg(str,P_NOATCODES|P_SAVEATR);
477: if(!cr) {
478: if(strlen(ptr)>LEN_FDESC)
479: cr=ptr+LEN_FDESC;
480: else
481: break; }
482: if(!(*(cr+1)) || !(*(cr+2)))
483: break;
484: bprintf("%21s",nulstr);
485: ptr=cr;
486: if(!(*ptr)) ptr++;
487: while(*ptr==LF || *ptr==CR) ptr++; }
488: return(true);
489: }
490:
491: /****************************************************************************/
492: /* Remove credits from uploader of file 'f' */
493: /****************************************************************************/
494: bool sbbs_t::removefcdt(file_t* f)
495: {
496: char str[128];
497: char tmp[512];
498: int u;
499: long cdt;
500:
501: if((u=matchuser(&cfg,f->uler,TRUE /*sysop_alias*/))==0) {
502: bputs(text[UnknownUser]);
503: return(false); }
504: cdt=0L;
505: if(cfg.dir[f->dir]->misc&DIR_CDTMIN && cur_cps) {
506: if(cfg.dir[f->dir]->misc&DIR_CDTUL)
507: cdt=((ulong)(f->cdt*(cfg.dir[f->dir]->up_pct/100.0))/cur_cps)/60;
508: if(cfg.dir[f->dir]->misc&DIR_CDTDL
509: && f->timesdled) /* all downloads */
510: cdt+=((ulong)((long)f->timesdled
511: *f->cdt*(cfg.dir[f->dir]->dn_pct/100.0))/cur_cps)/60;
512: adjustuserrec(&cfg,u,U_MIN,10,-cdt);
513: sprintf(str,"%lu minute",cdt);
514: sprintf(tmp,text[FileRemovedUserMsg]
515: ,f->name,cdt ? str : text[No]);
516: putsmsg(&cfg,u,tmp); }
517: else {
518: if(cfg.dir[f->dir]->misc&DIR_CDTUL)
519: cdt=(ulong)(f->cdt*(cfg.dir[f->dir]->up_pct/100.0));
520: if(cfg.dir[f->dir]->misc&DIR_CDTDL
521: && f->timesdled) /* all downloads */
522: cdt+=(ulong)((long)f->timesdled
523: *f->cdt*(cfg.dir[f->dir]->dn_pct/100.0));
524: adjustuserrec(&cfg,u,U_CDT,10,-cdt);
525: sprintf(tmp,text[FileRemovedUserMsg]
526: ,f->name,cdt ? ultoac(cdt,str) : text[No]);
527: putsmsg(&cfg,u,tmp); }
528:
529: adjustuserrec(&cfg,u,U_ULB,10,-f->size);
530: adjustuserrec(&cfg,u,U_ULS,5,-1);
531: return(true);
532: }
533:
534: /****************************************************************************/
535: /* Move file 'f' from f.dir to newdir */
536: /****************************************************************************/
537: bool sbbs_t::movefile(file_t* f, int newdir)
538: {
539: char str[MAX_PATH+1],path[MAX_PATH+1],fname[128],ext[1024];
540: int olddir=f->dir;
541:
542: if(findfile(&cfg,newdir,f->name)) {
543: bprintf(text[FileAlreadyThere],f->name);
544: return(false);
545: }
546: getextdesc(&cfg,olddir,f->datoffset,ext);
547: if(cfg.dir[olddir]->misc&DIR_MOVENEW)
548: f->dateuled=time(NULL);
549: unpadfname(f->name,fname);
550: removefiledat(&cfg,f);
551: f->dir=newdir;
552: addfiledat(&cfg,f);
553: bprintf(text[MovedFile],f->name
554: ,cfg.lib[cfg.dir[f->dir]->lib]->sname,cfg.dir[f->dir]->sname);
555: sprintf(str,"%s moved %s to %s %s",f->name
556: ,useron.alias
557: ,cfg.lib[cfg.dir[f->dir]->lib]->sname,cfg.dir[f->dir]->sname);
558: logline(nulstr,str);
559: if(!f->altpath) { /* move actual file */
560: sprintf(str,"%s%s",cfg.dir[olddir]->path,fname);
561: if(fexistcase(str)) {
562: sprintf(path,"%s%s",cfg.dir[f->dir]->path,getfname(str));
563: mv(str,path,0);
564: }
565: }
566: if(f->misc&FM_EXTDESC)
567: putextdesc(&cfg,f->dir,f->datoffset,ext);
568: return(true);
569: }
570:
571: /****************************************************************************/
572: /* Batch flagging prompt for download, extended info, and archive viewing */
573: /* Returns -1 if 'Q' or Ctrl-C, 0 if skip, 1 if [Enter], 2 otherwise */
574: /* or 3, backwards. */
575: /****************************************************************************/
576: int sbbs_t::batchflagprompt(uint dirnum, file_t* bf, uint total
577: ,long totalfiles)
578: {
579: char ch,c,d,str[256],fname[128],*p,remcdt=0,remfile=0;
580: char tmp[512];
581: uint i,j,ml=0,md=0,udir,ulib;
582: file_t f;
583:
584: for(ulib=0;ulib<usrlibs;ulib++)
585: if(usrlib[ulib]==cfg.dir[dirnum]->lib)
586: break;
587: for(udir=0;udir<usrdirs[ulib];udir++)
588: if(usrdir[ulib][udir]==dirnum)
589: break;
590:
591: CRLF;
592: while(online) {
593: bprintf(text[BatchFlagPrompt]
594: ,ulib+1
595: ,cfg.lib[cfg.dir[dirnum]->lib]->sname
596: ,udir+1
597: ,cfg.dir[dirnum]->sname
598: ,totalfiles);
599: ch=getkey(K_UPPER);
600: clearline();
601: if(ch=='?') {
602: menu("batflag");
603: if(lncntr)
604: pause();
605: return(2); }
606: if(ch=='Q' || sys_status&SS_ABORT)
607: return(-1);
608: if(ch=='S')
609: return(0);
610: if(ch=='P' || ch=='-')
611: return(3);
612: if(ch=='B') { /* Flag for batch download */
613: if(useron.rest&FLAG('D')) {
614: bputs(text[R_Download]);
615: return(2); }
616: if(total==1) {
617: f.dir=dirnum;
618: strcpy(f.name,bf[0].name);
619: f.datoffset=bf[0].datoffset;
620: f.size=0;
621: getfiledat(&cfg,&f);
622: addtobatdl(&f);
623: CRLF;
624: return(2); }
625: bputs(text[BatchDlFlags]);
626: d=getstr(str,BF_MAX,K_UPPER|K_LOWPRIO|K_NOCRLF);
627: lncntr=0;
628: if(sys_status&SS_ABORT)
629: return(-1);
630: if(d) { /* d is string length */
631: CRLF;
632: lncntr=0;
633: for(c=0;c<d;c++) {
634: if(batdn_total>=cfg.max_batdn) {
635: bprintf(text[BatchDlQueueIsFull],str+c);
636: break; }
637: if(strchr(str+c,'.')) { /* filename or spec given */
638: f.dir=dirnum;
639: p=strchr(str+c,' ');
640: if(!p) p=strchr(str+c,',');
641: if(p) *p=0;
642: for(i=0;i<total;i++) {
643: if(batdn_total>=cfg.max_batdn) {
644: bprintf(text[BatchDlQueueIsFull],str+c);
645: break; }
646: padfname(str+c,tmp);
647: if(filematch(bf[i].name,tmp)) {
648: strcpy(f.name,bf[i].name);
649: f.datoffset=bf[i].datoffset;
650: f.size=0;
651: getfiledat(&cfg,&f);
652: addtobatdl(&f); } } }
653: if(strchr(str+c,'.'))
654: c+=strlen(str+c);
655: else if(str[c]<'A'+(char)total && str[c]>='A') {
656: f.dir=dirnum;
657: strcpy(f.name,bf[str[c]-'A'].name);
658: f.datoffset=bf[str[c]-'A'].datoffset;
659: f.size=0;
660: getfiledat(&cfg,&f);
661: addtobatdl(&f); } }
662: CRLF;
663: return(2); }
664: clearline();
665: continue; }
666:
667: if(ch=='E' || ch=='V') { /* Extended Info */
668: if(total==1) {
669: f.dir=dirnum;
670: strcpy(f.name,bf[0].name);
671: f.datoffset=bf[0].datoffset;
672: f.dateuled=bf[0].dateuled;
673: f.datedled=bf[0].datedled;
674: f.size=0;
675: getfiledat(&cfg,&f);
676: if(!viewfile(&f,ch=='E'))
677: return(-1);
678: return(2); }
679: bputs(text[BatchDlFlags]);
680: d=getstr(str,BF_MAX,K_UPPER|K_LOWPRIO|K_NOCRLF);
681: lncntr=0;
682: if(sys_status&SS_ABORT)
683: return(-1);
684: if(d) { /* d is string length */
685: CRLF;
686: lncntr=0;
687: for(c=0;c<d;c++) {
688: if(strchr(str+c,'.')) { /* filename or spec given */
689: f.dir=dirnum;
690: p=strchr(str+c,' ');
691: if(!p) p=strchr(str+c,',');
692: if(p) *p=0;
693: for(i=0;i<total;i++) {
694: padfname(str+c,tmp);
695: if(filematch(bf[i].name,tmp)) {
696: strcpy(f.name,bf[i].name);
697: f.datoffset=bf[i].datoffset;
698: f.dateuled=bf[i].dateuled;
699: f.datedled=bf[i].datedled;
700: f.size=0;
701: getfiledat(&cfg,&f);
702: if(!viewfile(&f,ch=='E'))
703: return(-1); } } }
704: if(strchr(str+c,'.'))
705: c+=strlen(str+c);
706: else if(str[c]<'A'+(char)total && str[c]>='A') {
707: f.dir=dirnum;
708: strcpy(f.name,bf[str[c]-'A'].name);
709: f.datoffset=bf[str[c]-'A'].datoffset;
710: f.dateuled=bf[str[c]-'A'].dateuled;
711: f.datedled=bf[str[c]-'A'].datedled;
712: f.size=0;
713: getfiledat(&cfg,&f);
714: if(!viewfile(&f,ch=='E'))
715: return(-1); } }
716: return(2); }
717: clearline();
718: continue; }
719:
720: if((ch=='D' || ch=='M') /* Delete or Move */
721: && !(useron.rest&FLAG('R'))
722: && (dir_op(dirnum) || useron.exempt&FLAG('R'))) {
723: if(total==1) {
724: strcpy(str,"A");
725: d=1; }
726: else {
727: bputs(text[BatchDlFlags]);
728: d=getstr(str,BF_MAX,K_UPPER|K_LOWPRIO|K_NOCRLF); }
729: lncntr=0;
730: if(sys_status&SS_ABORT)
731: return(-1);
732: if(d) { /* d is string length */
733: CRLF;
734: if(ch=='D') {
735: if(noyes(text[AreYouSureQ]))
736: return(2);
737: remcdt=remfile=1;
738: if(dir_op(dirnum)) {
739: remcdt=!noyes(text[RemoveCreditsQ]);
740: remfile=!noyes(text[DeleteFileQ]); } }
741: else if(ch=='M') {
742: CRLF;
743: for(i=0;i<usrlibs;i++)
744: bprintf(text[MoveToLibLstFmt],i+1,cfg.lib[usrlib[i]]->lname);
745: SYNC;
746: bprintf(text[MoveToLibPrompt],cfg.dir[dirnum]->lib+1);
747: if((int)(ml=getnum(usrlibs))==-1)
748: return(2);
749: if(!ml)
750: ml=cfg.dir[dirnum]->lib;
751: else
752: ml--;
753: CRLF;
754: for(j=0;j<usrdirs[ml];j++)
755: bprintf(text[MoveToDirLstFmt]
756: ,j+1,cfg.dir[usrdir[ml][j]]->lname);
757: SYNC;
758: bprintf(text[MoveToDirPrompt],usrdirs[ml]);
759: if((int)(md=getnum(usrdirs[ml]))==-1)
760: return(2);
761: if(!md)
762: md=usrdirs[ml]-1;
763: else md--;
764: CRLF; }
765: lncntr=0;
766: for(c=0;c<d;c++) {
767: if(strchr(str+c,'.')) { /* filename or spec given */
768: f.dir=dirnum;
769: p=strchr(str+c,' ');
770: if(!p) p=strchr(str+c,',');
771: if(p) *p=0;
772: for(i=0;i<total;i++) {
773: padfname(str+c,tmp);
774: if(filematch(bf[i].name,tmp)) {
775: strcpy(f.name,bf[i].name);
776: unpadfname(f.name,fname);
777: f.datoffset=bf[i].datoffset;
778: f.dateuled=bf[i].dateuled;
779: f.datedled=bf[i].datedled;
780: f.size=0;
781: getfiledat(&cfg,&f);
782: if(f.opencount) {
783: bprintf(text[FileIsOpen]
784: ,f.opencount,f.opencount>1 ? "s":nulstr);
785: continue; }
786: if(ch=='D') {
787: removefiledat(&cfg,&f);
788: if(remfile) {
789: sprintf(tmp,"%s%s",cfg.dir[f.dir]->path,fname);
790: remove(tmp); }
791: if(remcdt)
792: removefcdt(&f); }
793: else if(ch=='M')
794: movefile(&f,usrdir[ml][md]); } } }
795: if(strchr(str+c,'.'))
796: c+=strlen(str+c);
797: else if(str[c]<'A'+(char)total && str[c]>='A') {
798: f.dir=dirnum;
799: strcpy(f.name,bf[str[c]-'A'].name);
800: unpadfname(f.name,fname);
801: f.datoffset=bf[str[c]-'A'].datoffset;
802: f.dateuled=bf[str[c]-'A'].dateuled;
803: f.datedled=bf[str[c]-'A'].datedled;
804: f.size=0;
805: getfiledat(&cfg,&f);
806: if(f.opencount) {
807: bprintf(text[FileIsOpen]
808: ,f.opencount,f.opencount>1 ? "s":nulstr);
809: continue; }
810: if(ch=='D') {
811: removefiledat(&cfg,&f);
812: if(remfile) {
813: sprintf(tmp,"%s%s",cfg.dir[f.dir]->path,fname);
814: remove(tmp); }
815: if(remcdt)
816: removefcdt(&f); }
817: else if(ch=='M')
818: movefile(&f,usrdir[ml][md]); } }
819: return(2); }
820: clearline();
821: continue; }
822:
823: return(1); }
824:
825: return(-1);
826: }
827:
828: /****************************************************************************/
829: /* List detailed information about the files in 'filespec'. Prompts for */
830: /* action depending on 'mode.' */
831: /* Returns number of files matching filespec that were found */
832: /****************************************************************************/
833: int sbbs_t::listfileinfo(uint dirnum, char *filespec, long mode)
834: {
835: char str[258],path[258],dirpath[256],done=0,ch,fname[13],ext[513];
836: char tmp[512];
837: uchar *ixbbuf,*usrxfrbuf=NULL,*p;
838: int file;
839: int error;
840: int found=0;
841: uint i,j;
842: long usrxfrlen=0;
843: long m,l;
844: long usrcdt;
845: time_t start,end,t;
846: file_t f;
847: struct tm tm;
848:
849: sprintf(str,"%sxfer.ixt",cfg.data_dir);
850: if(mode==FI_USERXFER) {
851: if(flength(str)<1L)
852: return(0);
853: if((file=nopen(str,O_RDONLY))==-1) {
854: errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
855: return(0); }
856: usrxfrlen=filelength(file);
857: if((usrxfrbuf=(uchar *)malloc(usrxfrlen))==NULL) {
858: close(file);
859: errormsg(WHERE,ERR_ALLOC,str,usrxfrlen);
860: return(0); }
861: if(read(file,usrxfrbuf,usrxfrlen)!=usrxfrlen) {
862: close(file);
863: free(usrxfrbuf);
864: errormsg(WHERE,ERR_READ,str,usrxfrlen);
865: return(0); }
866: close(file); }
867: sprintf(str,"%s%s.ixb",cfg.dir[dirnum]->data_dir,cfg.dir[dirnum]->code);
868: if((file=nopen(str,O_RDONLY))==-1)
869: return(0);
870: l=filelength(file);
871: if(!l) {
872: close(file);
873: return(0); }
874: if((ixbbuf=(uchar *)malloc(l))==NULL) {
875: close(file);
876: errormsg(WHERE,ERR_ALLOC,str,l);
877: return(0); }
878: if(lread(file,ixbbuf,l)!=l) {
879: close(file);
880: errormsg(WHERE,ERR_READ,str,l);
881: free((char *)ixbbuf);
882: if(usrxfrbuf)
883: free(usrxfrbuf);
884: return(0); }
885: close(file);
886: sprintf(str,"%s%s.dat",cfg.dir[dirnum]->data_dir,cfg.dir[dirnum]->code);
887: if((file=nopen(str,O_RDONLY))==-1) {
888: errormsg(WHERE,ERR_READ,str,O_RDONLY);
889: free((char *)ixbbuf);
890: if(usrxfrbuf)
891: free(usrxfrbuf);
892: return(0); }
893: close(file);
894: m=0;
895: while(online && !done && m<l) {
896: if(mode==FI_REMOVE && dir_op(dirnum))
897: action=NODE_SYSP;
898: else action=NODE_LFIL;
899: if(msgabort()) {
900: found=-1;
901: break; }
902: for(i=0;i<12 && m<l;i++)
903: if(i==8)
904: str[i]=ixbbuf[m]>' ' ? '.' : ' ';
905: else
906: str[i]=ixbbuf[m++]; /* Turns FILENAMEEXT into FILENAME.EXT */
907: str[i]=0;
908: unpadfname(str,fname);
909: if(filespec[0] && !filematch(str,filespec)) {
910: m+=11;
911: continue; }
912: f.datoffset=ixbbuf[m]|((long)ixbbuf[m+1]<<8)|((long)ixbbuf[m+2]<<16);
913: f.dateuled=ixbbuf[m+3]|((long)ixbbuf[m+4]<<8)
914: |((long)ixbbuf[m+5]<<16)|((long)ixbbuf[m+6]<<24);
915: f.datedled=ixbbuf[m+7]|((long)ixbbuf[m+8]<<8)
916: |((long)ixbbuf[m+9]<<16)|((long)ixbbuf[m+10]<<24);
917: m+=11;
918: if(mode==FI_OLD && f.datedled>ns_time)
919: continue;
920: if((mode==FI_OLDUL || mode==FI_OLD) && f.dateuled>ns_time)
921: continue;
922: f.dir=curdirnum=dirnum;
923: strcpy(f.name,str);
924: f.size=0;
925: getfiledat(&cfg,&f);
926: if(mode==FI_OFFLINE && f.size>=0)
927: continue;
928: if(f.altpath>0 && f.altpath<=cfg.altpaths)
929: strcpy(dirpath,cfg.altpath[f.altpath-1]);
930: else
931: strcpy(dirpath,cfg.dir[f.dir]->path);
932: if(mode==FI_CLOSE && !f.opencount)
933: continue;
934: if(mode==FI_USERXFER) {
935: for(p=usrxfrbuf;p<usrxfrbuf+usrxfrlen;p+=24) {
936: sprintf(str,"%17.17s",p); /* %4.4u %12.12s */
937: if(!strcmp(str+5,f.name) && useron.number==atoi(str))
938: break; }
939: if(p>=usrxfrbuf+usrxfrlen) /* file wasn't found */
940: continue; }
941: if((mode==FI_REMOVE) && (!dir_op(dirnum) && stricmp(f.uler
942: ,useron.alias) && !(useron.exempt&FLAG('R'))))
943: continue;
944: found++;
945: if(mode==FI_INFO) {
946: if(!viewfile(&f,1)) {
947: done=1;
948: found=-1; } }
949: else
950: fileinfo(&f);
951: if(mode==FI_CLOSE) {
952: if(!noyes(text[CloseFileRecordQ])) {
953: f.opencount=0;
954: putfiledat(&cfg,&f); } }
955: else if(mode==FI_REMOVE || mode==FI_OLD || mode==FI_OLDUL
956: || mode==FI_OFFLINE) {
957: SYNC;
958: CRLF;
959: if(f.opencount) {
960: mnemonics(text[QuitOrNext]);
961: strcpy(str,"Q\r"); }
962: else if(dir_op(dirnum)) {
963: mnemonics(text[SysopRemoveFilePrompt]);
964: strcpy(str,"VEFMCQR\r"); }
965: else if(useron.exempt&FLAG('R')) {
966: mnemonics(text[RExemptRemoveFilePrompt]);
967: strcpy(str,"VEMQR\r"); }
968: else {
969: mnemonics(text[UserRemoveFilePrompt]);
970: strcpy(str,"VEQR\r"); }
971: switch(getkeys(str,0)) {
972: case 'V':
973: viewfilecontents(&f);
974: CRLF;
975: ASYNC;
976: pause();
977: m-=F_IXBSIZE;
978: continue;
979: case 'E': /* edit file information */
980: if(dir_op(dirnum)) {
981: bputs(text[EditFilename]);
982: strcpy(str,fname);
983: if(!getstr(str,12,K_EDIT|K_AUTODEL))
984: break;
985: if(strcmp(str,fname)) { /* rename */
986: padfname(str,path);
987: if(stricmp(str,fname)
988: && findfile(&cfg,f.dir,path))
989: bprintf(text[FileAlreadyThere],path);
990: else {
991: sprintf(path,"%s%s",dirpath,fname);
992: sprintf(tmp,"%s%s",dirpath,str);
993: if(fexistcase(path) && rename(path,tmp))
994: bprintf(text[CouldntRenameFile],path,tmp);
995: else {
996: bprintf(text[FileRenamed],path,tmp);
997: strcpy(fname,str);
998: removefiledat(&cfg,&f);
999: strcpy(f.name,padfname(str,tmp));
1000: addfiledat(&cfg,&f);
1001: }
1002: }
1003: }
1004: }
1005: bputs(text[EditDescription]);
1006: getstr(f.desc,LEN_FDESC,K_LINE|K_EDIT|K_AUTODEL);
1007: if(sys_status&SS_ABORT)
1008: break;
1009: if(f.misc&FM_EXTDESC) {
1010: if(!noyes(text[DeleteExtDescriptionQ])) {
1011: remove(str);
1012: f.misc&=~FM_EXTDESC; } }
1013: if(!dir_op(dirnum)) {
1014: putfiledat(&cfg,&f);
1015: break; }
1016: bputs(text[EditUploader]);
1017: if(!getstr(f.uler,LEN_ALIAS,K_EDIT|K_AUTODEL))
1018: break;
1019: ultoa(f.cdt,str,10);
1020: bputs(text[EditCreditValue]);
1021: getstr(str,10,K_NUMBER|K_EDIT|K_AUTODEL);
1022: if(sys_status&SS_ABORT)
1023: break;
1024: f.cdt=atol(str);
1025: ultoa(f.timesdled,str,10);
1026: bputs(text[EditTimesDownloaded]);
1027: getstr(str,5,K_NUMBER|K_EDIT|K_AUTODEL);
1028: if(sys_status&SS_ABORT)
1029: break;
1030: f.timesdled=atoi(str);
1031: if(f.opencount) {
1032: ultoa(f.opencount,str,10);
1033: bputs(text[EditOpenCount]);
1034: getstr(str,3,K_NUMBER|K_EDIT|K_AUTODEL);
1035: f.opencount=atoi(str); }
1036: if(cfg.altpaths || f.altpath) {
1037: ultoa(f.altpath,str,10);
1038: bputs(text[EditAltPath]);
1039: getstr(str,3,K_NUMBER|K_EDIT|K_AUTODEL);
1040: f.altpath=atoi(str);
1041: if(f.altpath>cfg.altpaths)
1042: f.altpath=0; }
1043: if(sys_status&SS_ABORT)
1044: break;
1045: putfiledat(&cfg,&f);
1046: inputnstime(&f.dateuled);
1047: update_uldate(&cfg, &f);
1048: break;
1049: case 'F': /* delete file only */
1050: sprintf(str,"%s%s",dirpath,fname);
1051: if(!fexistcase(str))
1052: bputs(text[FileNotThere]);
1053: else {
1054: if(!noyes(text[AreYouSureQ])) {
1055: if(remove(str))
1056: bprintf(text[CouldntRemoveFile],str);
1057: else {
1058: sprintf(tmp,"%s deleted %s"
1059: ,useron.alias
1060: ,str);
1061: logline(nulstr,tmp);
1062: }
1063: }
1064: }
1065: break;
1066: case 'R': /* remove file from database */
1067: if(noyes(text[AreYouSureQ]))
1068: break;
1069: removefiledat(&cfg,&f);
1070: sprintf(str,"%s removed %s from %s %s"
1071: ,useron.alias
1072: ,f.name
1073: ,cfg.lib[cfg.dir[f.dir]->lib]->sname,cfg.dir[f.dir]->sname);
1074: logline("U-",str);
1075: sprintf(str,"%s%s",dirpath,fname);
1076: if(fexistcase(str)) {
1077: if(dir_op(dirnum)) {
1078: if(!noyes(text[DeleteFileQ])) {
1079: if(remove(str))
1080: bprintf(text[CouldntRemoveFile],str);
1081: else {
1082: sprintf(tmp,"%s deleted %s"
1083: ,useron.alias
1084: ,str);
1085: logline(nulstr,tmp);
1086: }
1087: }
1088: }
1089: else if(remove(str)) /* always remove if not sysop */
1090: bprintf(text[CouldntRemoveFile],str); }
1091: if(dir_op(dirnum) || useron.exempt&FLAG('R')) {
1092: i=cfg.lib[cfg.dir[f.dir]->lib]->offline_dir;
1093: if(i!=dirnum && i!=INVALID_DIR
1094: && !findfile(&cfg,i,f.name)) {
1095: sprintf(str,text[AddToOfflineDirQ]
1096: ,fname,cfg.lib[cfg.dir[i]->lib]->sname,cfg.dir[i]->sname);
1097: if(yesno(str)) {
1098: getextdesc(&cfg,f.dir,f.datoffset,ext);
1099: f.dir=i;
1100: addfiledat(&cfg,&f);
1101: if(f.misc&FM_EXTDESC)
1102: putextdesc(&cfg,f.dir,f.datoffset,ext); } } }
1103: if(dir_op(dirnum) || stricmp(f.uler,useron.alias)) {
1104: if(noyes(text[RemoveCreditsQ]))
1105: /* Fall through */ break; }
1106: case 'C': /* remove credits only */
1107: if((i=matchuser(&cfg,f.uler,TRUE /*sysop_alias*/))==0) {
1108: bputs(text[UnknownUser]);
1109: break; }
1110: if(dir_op(dirnum)) {
1111: usrcdt=(ulong)(f.cdt*(cfg.dir[f.dir]->up_pct/100.0));
1112: if(f.timesdled) /* all downloads */
1113: usrcdt+=(ulong)((long)f.timesdled
1114: *f.cdt*(cfg.dir[f.dir]->dn_pct/100.0));
1115: ultoa(usrcdt,str,10);
1116: bputs(text[CreditsToRemove]);
1117: getstr(str,10,K_NUMBER|K_LINE|K_EDIT|K_AUTODEL);
1118: f.cdt=atol(str); }
1119: usrcdt=adjustuserrec(&cfg,i,U_CDT,10,-(long)f.cdt);
1120: if(i==useron.number)
1121: useron.cdt=usrcdt;
1122: sprintf(str,text[FileRemovedUserMsg]
1123: ,f.name,f.cdt ? ultoac(f.cdt,tmp) : text[No]);
1124: putsmsg(&cfg,i,str);
1125: usrcdt=adjustuserrec(&cfg,i,U_ULB,10,-f.size);
1126: if(i==useron.number)
1127: useron.ulb=usrcdt;
1128: usrcdt=adjustuserrec(&cfg,i,U_ULS,5,-1);
1129: if(i==useron.number)
1130: useron.uls=(ushort)usrcdt;
1131: break;
1132: case 'M': /* move the file to another dir */
1133: CRLF;
1134: for(i=0;i<usrlibs;i++)
1135: bprintf(text[MoveToLibLstFmt],i+1,cfg.lib[usrlib[i]]->lname);
1136: SYNC;
1137: bprintf(text[MoveToLibPrompt],cfg.dir[dirnum]->lib+1);
1138: if((int)(i=getnum(usrlibs))==-1)
1139: continue;
1140: if(!i)
1141: i=cfg.dir[dirnum]->lib;
1142: else
1143: i--;
1144: CRLF;
1145: for(j=0;j<usrdirs[i];j++)
1146: bprintf(text[MoveToDirLstFmt]
1147: ,j+1,cfg.dir[usrdir[i][j]]->lname);
1148: SYNC;
1149: bprintf(text[MoveToDirPrompt],usrdirs[i]);
1150: if((int)(j=getnum(usrdirs[i]))==-1)
1151: continue;
1152: if(!j)
1153: j=usrdirs[i]-1;
1154: else j--;
1155: CRLF;
1156: movefile(&f,usrdir[i][j]);
1157: break;
1158: case 'Q': /* quit */
1159: found=-1;
1160: done=1;
1161: break; } }
1162: else if(mode==FI_DOWNLOAD || mode==FI_USERXFER) {
1163: sprintf(path,"%s%s",dirpath,fname);
1164: if(f.size<1L) { /* getfiledat will set this to -1 if non-existant */
1165: SYNC; /* and 0 byte files shouldn't be d/led */
1166: mnemonics(text[QuitOrNext]);
1167: if(getkeys("\rQ",0)=='Q') {
1168: found=-1;
1169: break; }
1170: continue; }
1171: if(!is_download_free(&cfg,f.dir,&useron)
1172: && f.cdt>(useron.cdt+useron.freecdt)) {
1173: SYNC;
1174: bprintf(text[YouOnlyHaveNCredits]
1175: ,ultoac(useron.cdt+useron.freecdt,tmp));
1176: mnemonics(text[QuitOrNext]);
1177: if(getkeys("\rQ",0)=='Q') {
1178: found=-1;
1179: break; }
1180: continue; }
1181: if(!chk_ar(cfg.dir[f.dir]->dl_ar,&useron)) {
1182: SYNC;
1183: bputs(text[CantDownloadFromDir]);
1184: mnemonics(text[QuitOrNext]);
1185: if(getkeys("\rQ",0)=='Q') {
1186: found=-1;
1187: break; }
1188: continue; }
1189: if(!(cfg.dir[f.dir]->misc&DIR_TFREE) && f.timetodl>timeleft && !dir_op(dirnum)
1190: && !(useron.exempt&FLAG('T'))) {
1191: SYNC;
1192: bputs(text[NotEnoughTimeToDl]);
1193: mnemonics(text[QuitOrNext]);
1194: if(getkeys("\rQ",0)=='Q') {
1195: found=-1;
1196: break; }
1197: continue; }
1198: xfer_prot_menu(XFER_DOWNLOAD);
1199: openfile(&f);
1200: SYNC;
1201: mnemonics(text[ProtocolBatchQuitOrNext]);
1202: strcpy(str,"BQ\r");
1203: for(i=0;i<cfg.total_prots;i++)
1204: if(cfg.prot[i]->dlcmd[0]
1205: && chk_ar(cfg.prot[i]->ar,&useron)) {
1206: sprintf(tmp,"%c",cfg.prot[i]->mnemonic);
1207: strcat(str,tmp); }
1208: // ungetkey(useron.prot);
1209: ch=(char)getkeys(str,0);
1210: if(ch=='Q') {
1211: found=-1;
1212: done=1; }
1213: else if(ch=='B') {
1214: if(!addtobatdl(&f)) {
1215: closefile(&f);
1216: break; } }
1217: else if(ch!=CR) {
1218: for(i=0;i<cfg.total_prots;i++)
1219: if(cfg.prot[i]->dlcmd[0] && cfg.prot[i]->mnemonic==ch
1220: && chk_ar(cfg.prot[i]->ar,&useron))
1221: break;
1222: if(i<cfg.total_prots) {
1223: #if 0 /* no such thing as local logon */
1224: if(online==ON_LOCAL) {
1225: bputs(text[EnterPath]);
1226: if(getstr(path,60,K_LINE)) {
1227: backslash(path);
1228: strcat(path,fname);
1229: sprintf(str,"%s%s",dirpath,fname);
1230: if(!mv(str,path,1))
1231: downloadfile(&f);
1232: for(j=0;j<cfg.total_dlevents;j++)
1233: if(!stricmp(cfg.dlevent[j]->ext,f.name+9)
1234: && chk_ar(cfg.dlevent[j]->ar,&useron)) {
1235: bputs(cfg.dlevent[j]->workstr);
1236: external(cmdstr(cfg.dlevent[j]->cmd,path,nulstr
1237: ,NULL)
1238: ,EX_OUTL);
1239: CRLF; }
1240: } }
1241: else
1242: #endif
1243: {
1244: delfiles(cfg.temp_dir,ALLFILES);
1245: if(cfg.dir[f.dir]->seqdev) {
1246: lncntr=0;
1247: seqwait(cfg.dir[f.dir]->seqdev);
1248: bprintf(text[RetrievingFile],fname);
1249: sprintf(str,"%s%s",dirpath,fname);
1250: sprintf(path,"%s%s",cfg.temp_dir,fname);
1251: mv(str,path,1); /* copy the file to temp dir */
1252: if(getnodedat(cfg.node_num,&thisnode,true)==0) {
1253: thisnode.aux=0xf0;
1254: putnodedat(cfg.node_num,&thisnode);
1255: }
1256: CRLF;
1257: }
1258: for(j=0;j<cfg.total_dlevents;j++)
1259: if(!stricmp(cfg.dlevent[j]->ext,f.name+9)
1260: && chk_ar(cfg.dlevent[j]->ar,&useron)) {
1261: bputs(cfg.dlevent[j]->workstr);
1262: external(cmdstr(cfg.dlevent[j]->cmd,path,nulstr,NULL)
1263: ,EX_OUTL);
1264: CRLF; }
1265: getnodedat(cfg.node_num,&thisnode,1);
1266: action=NODE_DLNG;
1267: t=now+f.timetodl;
1268: localtime_r(&t,&tm);
1269: thisnode.aux=(tm.tm_hour*60)+tm.tm_min;
1270: putnodedat(cfg.node_num,&thisnode); /* calculate ETA */
1271: start=time(NULL);
1272: error=protocol(cfg.prot[i],XFER_DOWNLOAD,path,nulstr,false);
1273: end=time(NULL);
1274: if(cfg.dir[f.dir]->misc&DIR_TFREE)
1275: starttime+=end-start;
1276: if(checkprotresult(cfg.prot[i],error,&f))
1277: downloadfile(&f);
1278: else
1279: notdownloaded(f.size,start,end);
1280: delfiles(cfg.temp_dir,ALLFILES);
1281: autohangup();
1282: }
1283: }
1284: }
1285: closefile(&f); }
1286: if(filespec[0] && !strchr(filespec,'*') && !strchr(filespec,'?'))
1287: break;
1288: }
1289: free((char *)ixbbuf);
1290: if(usrxfrbuf)
1291: free(usrxfrbuf);
1292: return(found);
1293: }
1294:
1295: /****************************************************************************/
1296: /* Prints one file's information on a single line to a file 'file' */
1297: /****************************************************************************/
1298: void sbbs_t::listfiletofile(char *fname, char *buf, uint dirnum, int file)
1299: {
1300: char str[256];
1301: char tmp[512];
1302: uchar alt;
1303: ulong cdt;
1304: bool exist=true;
1305:
1306: strcpy(str,fname);
1307: if(buf[F_MISC]!=ETX && (buf[F_MISC]-' ')&FM_EXTDESC)
1308: strcat(str,"+");
1309: else
1310: strcat(str," ");
1311: write(file,str,13);
1312: getrec((char *)buf,F_ALTPATH,2,str);
1313: alt=(uchar)ahtoul(str);
1314: sprintf(str,"%s%s",alt>0 && alt<=cfg.altpaths ? cfg.altpath[alt-1]
1315: : cfg.dir[dirnum]->path,unpadfname(fname,tmp));
1316: if(cfg.dir[dirnum]->misc&DIR_FCHK && !fexistcase(str))
1317: exist=false;
1318: getrec((char *)buf,F_CDT,LEN_FCDT,str);
1319: cdt=atol(str);
1320: if(!cdt)
1321: strcpy(str," FREE");
1322: else
1323: sprintf(str,"%7lu",cdt);
1324: if(exist)
1325: strcat(str," ");
1326: else
1327: strcat(str,"-");
1328: write(file,str,8);
1329: getrec((char *)buf,F_DESC,LEN_FDESC,str);
1330: write(file,str,strlen(str));
1331: write(file,crlf,2);
1332: }
1333:
1334: int extdesclines(char *str)
1335: {
1336: int i,lc,last;
1337:
1338: for(i=lc=last=0;str[i];i++)
1339: if(str[i]==LF || i-last>LEN_FDESC) {
1340: lc++;
1341: last=i; }
1342: return(lc);
1343: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.