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