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