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