|
|
1.1 root 1: /* tmp_xfer.cpp */
2:
3: /* Synchronet temp directory file transfer routines */
4:
1.1.1.2 ! root 5: /* $Id: tmp_xfer.cpp,v 1.47 2011/09/21 03:10:53 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 2011 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: /*****************************************************************************/
41: /* Temp directory section. Files must be extracted here and both temp_uler */
42: /* and temp_uler fields should be filled before entrance. */
43: /*****************************************************************************/
44: void sbbs_t::temp_xfer()
45: {
46: char str[256],tmp2[256],done=0,ch;
47: char tmp[512];
48: int error;
49: uint i,dirnum=cfg.total_dirs,files;
50: ulong bytes;
51: ulong space;
52: time_t start,end,t;
53: file_t f;
54: glob_t g;
55: struct tm tm;
56:
57: if(!usrlibs)
58: return;
59: if(useron.rest&FLAG('D')) {
60: bputs(text[R_Download]);
1.1.1.2 ! root 61: return;
! 62: }
1.1 root 63: /*************************************/
64: /* Create TEMP directory information */
65: /*************************************/
66: if((cfg.dir[dirnum]=(dir_t *)malloc(sizeof(dir_t)))==0) {
67: errormsg(WHERE,ERR_ALLOC,"temp_dir",sizeof(dir_t));
1.1.1.2 ! root 68: return;
! 69: }
1.1 root 70: memset(cfg.dir[dirnum],0,sizeof(dir_t));
71: SAFECOPY(cfg.dir[dirnum]->lname,"Temporary");
72: SAFECOPY(cfg.dir[dirnum]->sname,"Temp");
73: SAFECOPY(cfg.dir[dirnum]->code,"TEMP");
74: SAFECOPY(cfg.dir[dirnum]->path,cfg.temp_dir);
75: SAFECOPY(cfg.dir[dirnum]->data_dir,cfg.dir[0]->data_dir);
76: cfg.dir[dirnum]->maxfiles=MAX_FILES;
77: cfg.dir[dirnum]->op_ar=(uchar *)nulstr;
78: cfg.dir[dirnum]->ex_ar=(uchar *)nulstr;
79: temp_dirnum=curdirnum=usrdir[curlib][curdir[curlib]];
80: cfg.total_dirs++;
81:
82: /****************************/
83: /* Fill filedat information */
84: /****************************/
85: memset(&f,0,sizeof(f));
86: SAFEPRINTF2(f.name,"temp_%3.3d.%s",cfg.node_num,useron.tmpext);
87: SAFECOPY(f.desc,"Temp File");
88: f.dir=dirnum;
89:
90: if(useron.misc&(RIP|WIP|HTML) && !(useron.misc&EXPERT))
91: menu("tempxfer");
92: lncntr=0;
93: while(online && !done) {
94: if(!(useron.misc&(EXPERT|RIP|WIP|HTML))) {
95: sys_status&=~SS_ABORT;
96: if(lncntr) {
97: SYNC;
98: CRLF;
99: if(lncntr) /* CRLF or SYNC can cause pause */
1.1.1.2 ! root 100: pause();
! 101: }
! 102: menu("tempxfer");
! 103: }
1.1 root 104: ASYNC;
105: bputs(text[TempDirPrompt]);
106: SAFECOPY(f.uler,temp_uler);
107: ch=(char)getkeys("ADEFNILQRVX?\r",0);
108: if(ch>' ')
109: logch(ch,0);
110: switch(ch) {
111: case 'A': /* add to temp file */
1.1.1.2 ! root 112: if(!isdir(cfg.temp_dir)) {
! 113: bprintf(text[DirectoryDoesNotExist], cfg.temp_dir);
! 114: lprintf(LOG_ERR,"Temp directory does not exist: %s", cfg.temp_dir);
! 115: break;
! 116: }
1.1 root 117: /* free disk space */
118: space=getfreediskspace(cfg.temp_dir,1024);
119: if(space<(ulong)cfg.min_dspace) {
120: bputs(text[LowDiskSpace]);
1.1.1.2 ! root 121: lprintf(LOG_ERR,"Diskspace is low: %s (%lu kilobytes)"
1.1 root 122: ,cfg.temp_dir,space);
123: if(!dir_op(dirnum))
1.1.1.2 ! root 124: break;
! 125: }
1.1 root 126: bprintf(text[DiskNBytesFree],ultoac(space,tmp));
127: if(!getfilespec(str))
128: break;
129: if(!checkfname(str))
130: break;
1.1.1.2 ! root 131: SAFEPRINTF3(tmp2,"%s added %s to %s"
1.1 root 132: ,useron.alias,str,f.name);
133: logline(nulstr,tmp2);
1.1.1.2 ! root 134: SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,str);
! 135: SAFEPRINTF2(str,"%s%s",cfg.temp_dir,f.name);
! 136: external(cmdstr(temp_cmd(),str,tmp2,NULL),EX_WILDCARD|EX_STDOUT);
1.1 root 137: break;
138: case 'D': /* download from temp dir */
1.1.1.2 ! root 139: SAFEPRINTF2(str,"%s%s",cfg.temp_dir,f.name);
1.1 root 140: if(!fexist(str)) {
141: bprintf(text[TempFileNotCreatedYet],f.name);
1.1.1.2 ! root 142: break;
! 143: }
! 144: f.size=f.cdt=(long)flength(str);
1.1 root 145: f.opencount=0;
146: if(temp_cdt) /* if file was not free */
147: f.cdt=f.size;
148: else
149: f.cdt=0;
150: if(!(useron.exempt&FLAG('D'))
151: && f.cdt>useron.cdt+useron.freecdt) {
152: bprintf(text[YouOnlyHaveNCredits]
153: ,ultoac(useron.cdt+useron.freecdt,tmp));
1.1.1.2 ! root 154: break; /* f.cdt must equal size here */
! 155: }
1.1 root 156: if(!(useron.exempt&FLAG('T')) && !dir_op(dirnum)
157: && !(cfg.dir[temp_dirnum]->misc&DIR_TFREE) && cur_cps
158: && f.size/(ulong)cur_cps>timeleft) {
159: bputs(text[NotEnoughTimeToDl]);
1.1.1.2 ! root 160: break;
! 161: }
! 162: if(!chk_ar(cfg.dir[temp_dirnum]->dl_ar,&useron,&client)) {
1.1 root 163: bputs(text[CantDownloadFromDir]);
1.1.1.2 ! root 164: break;
! 165: }
1.1 root 166: addfiledat(&cfg,&f);
167: xfer_prot_menu(XFER_DOWNLOAD);
168: SYNC;
169: mnemonics(text[ProtocolOrQuit]);
170: SAFECOPY(tmp2,"Q");
171: for(i=0;i<cfg.total_prots;i++)
1.1.1.2 ! root 172: if(cfg.prot[i]->dlcmd[0] && chk_ar(cfg.prot[i]->ar,&useron,&client)) {
1.1 root 173: sprintf(tmp,"%c",cfg.prot[i]->mnemonic);
1.1.1.2 ! root 174: strcat(tmp2,tmp);
! 175: }
1.1 root 176: ungetkey(useron.prot);
177: ch=(char)getkeys(tmp2,0);
178: for(i=0;i<cfg.total_prots;i++)
179: if(cfg.prot[i]->dlcmd[0] && cfg.prot[i]->mnemonic==ch
1.1.1.2 ! root 180: && chk_ar(cfg.prot[i]->ar,&useron,&client))
1.1 root 181: break;
182: if(i<cfg.total_prots) {
183: getnodedat(cfg.node_num,&thisnode,1);
184: action=NODE_DLNG;
185: t=now;
186: if(cur_cps)
187: t+=(f.size/(ulong)cur_cps);
188: if(localtime_r(&t,&tm)==NULL)
189: break;
190: thisnode.aux=(tm.tm_hour*60)+tm.tm_min;
191:
192: putnodedat(cfg.node_num,&thisnode); /* calculate ETA */
193: start=time(NULL);
194: error=protocol(cfg.prot[i],XFER_DOWNLOAD,str,nulstr,false);
195: end=time(NULL);
196: if(cfg.dir[temp_dirnum]->misc&DIR_TFREE)
197: starttime+=end-start;
198: if(checkprotresult(cfg.prot[i],error,&f))
199: downloadfile(&f);
200: else
201: notdownloaded(f.size,start,end);
202: autohangup();
203: }
204: removefiledat(&cfg,&f);
205: break;
206: case 'E':
207: extract(usrdir[curlib][curdir[curlib]]);
208: sys_status&=~SS_ABORT;
209: break;
210: case 'F': /* Create a file list */
211: delfiles(cfg.temp_dir,ALLFILES);
212: create_filelist("FILELIST.TXT",0);
213: if(!(sys_status&SS_ABORT))
214: logline(nulstr,"Created list of all files");
215: CRLF;
216: sys_status&=~SS_ABORT;
217: break;
218: case 'I': /* information on what's here */
219: bprintf(text[TempFileInfo],f.uler,temp_file);
220: break;
221: case 'L': /* list files in dir */
222: if(!getfilespec(str))
223: break;
224: if(!checkfname(str))
225: break;
226: bytes=files=0L;
227: CRLF;
1.1.1.2 ! root 228: SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,str);
1.1 root 229: glob(tmp2,0,NULL,&g);
230: for(i=0;i<(uint)g.gl_pathc && !msgabort();i++) {
231: if(isdir(g.gl_pathv[i]))
232: continue;
233: t=fdate(g.gl_pathv[i]);
234: bprintf("%-25s %15s %s\r\n",getfname(g.gl_pathv[i])
1.1.1.2 ! root 235: ,ultoac((long)flength(g.gl_pathv[i]),tmp)
! 236: ,timestr(t));
1.1 root 237: files++;
1.1.1.2 ! root 238: bytes+=(long)flength(g.gl_pathv[i]);
1.1 root 239: }
240: globfree(&g);
241: if(!files)
242: bputs(text[EmptyDir]);
243: else if(files>1)
244: bprintf(text[TempDirTotal],ultoac(bytes,tmp),files);
245: break;
246: case 'N': /* Create a list of new files */
247: delfiles(cfg.temp_dir,ALLFILES);
248: create_filelist("NEWFILES.TXT",FL_ULTIME);
249: if(!(sys_status&SS_ABORT))
250: logline(nulstr,"Created list of new files");
251: CRLF;
252: sys_status&=~SS_ABORT;
253: break;
254: case 'R': /* Remove files from dir */
255: if(!getfilespec(str) || !checkfname(str))
256: break;
257: bprintf(text[NFilesRemoved],delfiles(cfg.temp_dir,str));
258: break;
259: case 'V': /* view files in dir */
260: bputs(text[FileSpec]);
261: if(!getstr(str,64,K_NONE) || !checkfname(str))
262: break;
263: viewfiles(dirnum,str);
264: break;
265: case CR:
266: case 'Q': /* quit */
267: done=1;
268: break;
269: case 'X': /* extract from archive in temp dir */
270: extract(dirnum);
271: sys_status&=~SS_ABORT;
272: break;
273: case '?': /* menu */
274: if(useron.misc&(EXPERT|RIP|WIP|HTML))
275: menu("tempxfer");
1.1.1.2 ! root 276: break;
! 277: }
1.1 root 278: if(sys_status&SS_ABORT)
1.1.1.2 ! root 279: break;
! 280: }
1.1 root 281: free(cfg.dir[dirnum]);
282: cfg.total_dirs--;
283: }
284:
285: /*****************************************************************************/
286: /* Handles extraction from a normal transfer file to the temp directory */
287: /*****************************************************************************/
288: void sbbs_t::extract(uint dirnum)
289: {
290: char fname[13],str[256],excmd[256],path[256],done
291: ,tmp[256],intmp=0;
292: uint i,j;
293: ulong space;
294: file_t f;
295: DIR* dir;
296: DIRENT* dirent;
297:
298: temp_dirnum=curdirnum=dirnum;
299: if(!strcmp(cfg.dir[dirnum]->code,"TEMP"))
300: intmp=1;
301:
1.1.1.2 ! root 302: if(!isdir(cfg.temp_dir)) {
! 303: bprintf(text[DirectoryDoesNotExist], cfg.temp_dir);
! 304: lprintf(LOG_ERR,"Temp directory does not exist: %s", cfg.temp_dir);
! 305: return;
! 306: }
! 307:
1.1 root 308: /* get free disk space */
309: space=getfreediskspace(cfg.temp_dir,1024);
310: if(space<(ulong)cfg.min_dspace) {
311: bputs(text[LowDiskSpace]);
1.1.1.2 ! root 312: lprintf(LOG_ERR,"Diskspace is low: %s (%lu kilobytes)",cfg.temp_dir,space);
1.1 root 313: if(!dir_op(dirnum))
1.1.1.2 ! root 314: return;
! 315: }
1.1 root 316: else if(!intmp) { /* not in temp dir */
1.1.1.2 ! root 317: CRLF;
! 318: }
1.1 root 319: bprintf(text[DiskNBytesFree],ultoac(space,tmp));
320:
321: if(!intmp) { /* not extracting FROM temp directory */
1.1.1.2 ! root 322: SAFEPRINTF2(str,"%s%s",cfg.temp_dir,ALLFILES);
1.1 root 323: if(fexist(str)) {
324: bputs(text[RemovingTempFiles]);
325: dir=opendir(cfg.temp_dir);
326: while(dir!=NULL && (dirent=readdir(dir))!=NULL) {
1.1.1.2 ! root 327: SAFEPRINTF2(str,"%s%s",cfg.temp_dir,dirent->d_name);
1.1 root 328: if(!isdir(str))
329: remove(str);
330: }
331: if(dir!=NULL)
332: closedir(dir);
333: CRLF;
334: }
335: }
336: bputs(text[ExtractFrom]);
1.1.1.2 ! root 337: if(!getstr(fname,sizeof(fname)-1,K_NONE) || !checkfname(fname) || strchr(fname,'*')
1.1 root 338: || strchr(fname,'?'))
339: return;
340: padfname(fname,f.name);
341: SAFECOPY(str,f.name);
342: truncsp(str);
343: for(i=0;i<cfg.total_fextrs;i++)
1.1.1.2 ! root 344: if(!stricmp(str+9,cfg.fextr[i]->ext) && chk_ar(cfg.fextr[i]->ar,&useron,&client)) {
1.1 root 345: SAFECOPY(excmd,cfg.fextr[i]->cmd);
1.1.1.2 ! root 346: break;
! 347: }
1.1 root 348: if(i==cfg.total_fextrs) {
349: bputs(text[UnextractableFile]);
1.1.1.2 ! root 350: return;
! 351: }
1.1 root 352: if(!intmp && !findfile(&cfg,dirnum,f.name)) { /* not temp dir */
353: bputs(text[SearchingAllDirs]);
354: for(i=0;i<usrdirs[curlib] && !msgabort();i++) {
355: if(i==dirnum) continue;
356: if(findfile(&cfg,usrdir[curlib][i],f.name))
1.1.1.2 ! root 357: break;
! 358: }
1.1 root 359: if(i==usrdirs[curlib]) { /* not found in cur lib */
360: bputs(text[SearchingAllLibs]);
361: for(i=j=0;i<usrlibs;i++) {
362: if(i==curlib) continue;
363: for(j=0;j<usrdirs[i] && !msgabort();j++)
364: if(findfile(&cfg,usrdir[i][j],f.name))
365: break;
366: if(j<usrdirs[i])
1.1.1.2 ! root 367: break;
! 368: }
1.1 root 369: if(i==usrlibs) {
370: bputs(text[FileNotFound]); /* not in database */
1.1.1.2 ! root 371: return;
! 372: }
! 373: dirnum=usrdir[i][j];
! 374: }
1.1 root 375: else
1.1.1.2 ! root 376: dirnum=usrdir[curlib][i];
! 377: }
1.1 root 378: if(sys_status&SS_ABORT)
379: return;
1.1.1.2 ! root 380: SAFEPRINTF2(path,"%s%s",cfg.dir[dirnum]->path,fname);
1.1 root 381: if(!intmp) { /* not temp dir, so get temp_file info */
382: f.datoffset=f.dateuled=f.datedled=0L;
383: f.dir=dirnum;
384: getfileixb(&cfg,&f);
385: if(!f.datoffset && !f.dateuled && !f.datedled) /* error reading ixb */
386: return;
387: f.size=0;
388: getfiledat(&cfg,&f);
389: fileinfo(&f);
390: if(f.altpath>0 && f.altpath<=cfg.altpaths)
1.1.1.2 ! root 391: SAFEPRINTF2(path,"%s%s",cfg.altpath[f.altpath-1],fname);
1.1 root 392: temp_dirnum=dirnum;
393: if(cfg.dir[f.dir]->misc&DIR_FREE)
394: temp_cdt=0L;
395: else
396: temp_cdt=f.cdt;
397: SAFECOPY(temp_uler,f.uler);
1.1.1.2 ! root 398: SAFECOPY(temp_file,f.name); /* padded filename */
! 399: }
1.1 root 400: if(!fexistcase(path)) {
1.1.1.2 ! root 401: bprintf(text[FileDoesNotExist],path); /* not on disk */
! 402: return;
! 403: }
1.1 root 404: done=0;
405: while(online && !done) {
406: mnemonics(text[ExtractFilesPrompt]);
407: switch(getkeys("EVQ",0)) {
408: case 'E':
409: if(!getfilespec(str))
410: break;
411: if(!checkfname(str))
412: break;
1.1.1.2 ! root 413: if((i=external(cmdstr(excmd,path,str,NULL),EX_STDIO))!=0) {
1.1 root 414: errormsg(WHERE,ERR_EXEC,cmdstr(excmd,path,str,NULL),i);
1.1.1.2 ! root 415: return;
! 416: }
! 417: SAFEPRINTF3(tmp,"%s extracted %s from %s",useron.alias,str,path);
1.1 root 418: logline(nulstr,tmp);
419: CRLF;
420: break;
421: case 'V':
422: viewfiles(dirnum,fname);
423: break;
424: default:
425: done=1;
1.1.1.2 ! root 426: break;
! 427: }
! 428: }
1.1 root 429: }
430:
431: /****************************************************************************/
432: /* Creates a text file named NEWFILES.DAT in the temp directory that */
433: /* all new files since p-date. Returns number of files in list. */
434: /****************************************************************************/
1.1.1.2 ! root 435: ulong sbbs_t::create_filelist(const char *name, long mode)
1.1 root 436: {
437: char str[256];
438: int file;
439: uint i,j,d;
440: ulong l,k;
441:
442: bprintf(text[CreatingFileList],name);
1.1.1.2 ! root 443: SAFEPRINTF2(str,"%s%s",cfg.temp_dir,name);
1.1 root 444: if((file=nopen(str,O_CREAT|O_WRONLY|O_APPEND))==-1) {
445: errormsg(WHERE,ERR_OPEN,str,O_CREAT|O_WRONLY|O_APPEND);
1.1.1.2 ! root 446: return(0);
! 447: }
1.1 root 448: k=0;
449: if(mode&FL_ULTIME) {
1.1.1.2 ! root 450: SAFEPRINTF(str,"New files since: %s\r\n",timestr(ns_time));
! 451: write(file,str,strlen(str));
! 452: }
1.1 root 453: for(i=j=d=0;i<usrlibs;i++) {
454: for(j=0;j<usrdirs[i];j++,d++) {
455: outchar('.');
456: if(d && !(d%5))
457: bputs("\b\b\b\b\b \b\b\b\b\b");
458: if(mode&FL_ULTIME /* New-scan */
459: && (cfg.lib[usrlib[i]]->offline_dir==usrdir[i][j]
460: || cfg.dir[usrdir[i][j]]->misc&DIR_NOSCAN))
461: continue;
462: l=listfiles(usrdir[i][j],nulstr,file,mode);
463: if((long)l==-1)
464: break;
1.1.1.2 ! root 465: k+=l;
! 466: }
1.1 root 467: if(j<usrdirs[i])
1.1.1.2 ! root 468: break;
! 469: }
1.1 root 470: if(k>1) {
1.1.1.2 ! root 471: SAFEPRINTF(str,"\r\n%ld Files Listed.\r\n",k);
! 472: write(file,str,strlen(str));
! 473: }
1.1 root 474: close(file);
475: if(k)
476: bprintf(text[CreatedFileList],name);
477: else {
478: bputs(text[NoFiles]);
1.1.1.2 ! root 479: SAFEPRINTF2(str,"%s%s",cfg.temp_dir,name);
! 480: remove(str);
! 481: }
1.1 root 482: SAFECOPY(temp_file,name);
483: SAFECOPY(temp_uler,"File List");
484: return(k);
485: }
486:
487: /****************************************************************************/
488: /* This function returns the command line for the temp file extension for */
489: /* current user online. */
490: /****************************************************************************/
491: char * sbbs_t::temp_cmd(void)
492: {
493: int i;
494:
495: if(!cfg.total_fcomps) {
496: errormsg(WHERE,ERR_CHK,"compressible file types",0);
1.1.1.2 ! root 497: return(nulstr);
! 498: }
1.1 root 499: for(i=0;i<cfg.total_fcomps;i++)
500: if(!stricmp(useron.tmpext,cfg.fcomp[i]->ext)
1.1.1.2 ! root 501: && chk_ar(cfg.fcomp[i]->ar,&useron,&client))
1.1 root 502: return(cfg.fcomp[i]->cmd);
503: return(cfg.fcomp[0]->cmd);
504: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.