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