|
|
1.1 root 1: /* file.cpp */
2:
3: /* Synchronet file transfer-related functions */
4:
1.1.1.2 ! root 5: /* $Id: file.cpp,v 1.28 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: /* Prints all information of file in file_t structure 'f' */
42: /****************************************************************************/
43: void sbbs_t::fileinfo(file_t* f)
44: {
45: char ext[513];
46: char tmp[512];
47: char path[MAX_PATH+1];
48: char fpath[MAX_PATH+1];
49: uint i,j;
50:
51: for(i=0;i<usrlibs;i++)
52: if(usrlib[i]==cfg.dir[f->dir]->lib)
53: break;
54: for(j=0;j<usrdirs[i];j++)
55: if(usrdir[i][j]==f->dir)
56: break;
57:
58: getfilepath(&cfg,f,path);
59: bprintf(text[FiLib],i+1,cfg.lib[cfg.dir[f->dir]->lib]->lname);
60: bprintf(text[FiDir],j+1,cfg.dir[f->dir]->lname);
61: bprintf(text[FiFilename],getfname(path));
62: SAFECOPY(fpath,path);
63: fexistcase(fpath);
64: if(strcmp(path,fpath) && strcmp(f->desc,getfname(fpath))) /* Different "actual" filename */
65: bprintf(text[FiFilename],getfname(fpath));
66:
67: if(f->size!=-1L)
68: bprintf(text[FiFileSize],ultoac(f->size,tmp));
69: bprintf(text[FiCredits]
70: ,(cfg.dir[f->dir]->misc&DIR_FREE || !f->cdt) ? "FREE" : ultoac(f->cdt,tmp));
71: bprintf(text[FiDescription],f->desc);
72: bprintf(text[FiUploadedBy],f->misc&FM_ANON ? text[UNKNOWN_USER] : f->uler);
73: if(f->date)
1.1.1.2 ! root 74: bprintf(text[FiFileDate],timestr(f->date));
! 75: bprintf(text[FiDateUled],timestr(f->dateuled));
! 76: bprintf(text[FiDateDled],f->datedled ? timestr(f->datedled) : "Never");
1.1 root 77: bprintf(text[FiTimesDled],f->timesdled);
78: if(f->size!=-1L)
79: bprintf(text[FiTransferTime],sectostr(f->timetodl,tmp));
80: if(f->altpath) {
81: if(f->altpath<=cfg.altpaths) {
82: if(SYSOP)
83: bprintf(text[FiAlternatePath],cfg.altpath[f->altpath-1]);
84: }
85: else
86: bprintf(text[InvalidAlternatePathN],f->altpath);
87: }
88: CRLF;
89: if(f->misc&FM_EXTDESC) {
90: getextdesc(&cfg,f->dir,f->datoffset,ext);
91: CRLF;
92: putmsg(ext,P_NOATCODES);
1.1.1.2 ! root 93: CRLF;
! 94: }
! 95: if(f->size==-1L) {
1.1 root 96: bprintf(text[FileIsNotOnline],f->name);
1.1.1.2 ! root 97: if(SYSOP)
! 98: bprintf("%s\r\n",fpath);
! 99: }
1.1 root 100: if(f->opencount)
101: bprintf(text[FileIsOpen],f->opencount,f->opencount>1 ? "s" : nulstr);
102:
103: }
104:
105:
106: /****************************************************************************/
107: /* Increments the opencount on the file data 'f' and adds the transaction */
108: /* to the backout.dab */
109: /****************************************************************************/
110: void sbbs_t::openfile(file_t* f)
111: {
112: char str1[256],str2[4],str3[4],ch;
113: int file;
114:
115: /************************************/
116: /* Increment open count in dat file */
117: /************************************/
118: sprintf(str1,"%s%s.dat",cfg.dir[f->dir]->data_dir,cfg.dir[f->dir]->code);
119: if((file=nopen(str1,O_RDWR))==-1) {
120: errormsg(WHERE,ERR_OPEN,str1,O_RDWR);
1.1.1.2 ! root 121: return;
! 122: }
1.1 root 123: lseek(file,f->datoffset+F_OPENCOUNT,SEEK_SET);
124: if(read(file,str2,3)!=3) {
125: close(file);
126: errormsg(WHERE,ERR_READ,str1,3);
1.1.1.2 ! root 127: return;
! 128: }
1.1 root 129: str2[3]=0;
130: ultoa(atoi(str2)+1,str3,10);
131: putrec(str2,0,3,str3);
132: lseek(file,f->datoffset+F_OPENCOUNT,SEEK_SET);
133: if(write(file,str2,3)!=3) {
134: close(file);
135: errormsg(WHERE,ERR_WRITE,str1,3);
1.1.1.2 ! root 136: return;
! 137: }
1.1 root 138: close(file);
139: /**********************************/
140: /* Add transaction to BACKOUT.DAB */
141: /**********************************/
142: sprintf(str1,"%sbackout.dab",cfg.node_dir);
143: if((file=nopen(str1,O_WRONLY|O_APPEND|O_CREAT))==-1) {
144: errormsg(WHERE,ERR_OPEN,str1,O_WRONLY|O_APPEND|O_CREAT);
1.1.1.2 ! root 145: return;
! 146: }
1.1 root 147: ch=BO_OPENFILE;
148: write(file,&ch,1); /* backout type */
149: write(file,cfg.dir[f->dir]->code,8); /* directory code */
150: write(file,&f->datoffset,4); /* offset into .dat file */
151: write(file,&ch,BO_LEN-(1+8+4)); /* pad it */
152: close(file);
153: }
154:
155: /****************************************************************************/
156: /* Decrements the opencount on the file data 'f' and removes the backout */
157: /* from the backout.dab */
158: /****************************************************************************/
159: void sbbs_t::closefile(file_t* f)
160: {
161: char str1[256],str2[4],str3[4],ch,*buf;
162: int file;
163: long length,l,offset;
164:
165: /************************************/
166: /* Decrement open count in dat file */
167: /************************************/
168: sprintf(str1,"%s%s.dat",cfg.dir[f->dir]->data_dir,cfg.dir[f->dir]->code);
169: if((file=nopen(str1,O_RDWR))==-1) {
170: errormsg(WHERE,ERR_OPEN,str1,O_RDWR);
1.1.1.2 ! root 171: return;
! 172: }
1.1 root 173: lseek(file,f->datoffset+F_OPENCOUNT,SEEK_SET);
174: if(read(file,str2,3)!=3) {
175: close(file);
176: errormsg(WHERE,ERR_READ,str1,3);
1.1.1.2 ! root 177: return;
! 178: }
1.1 root 179: str2[3]=0;
180: ch=atoi(str2);
181: if(ch) ch--;
182: ultoa(ch,str3,10);
183: putrec(str2,0,3,str3);
184: lseek(file,f->datoffset+F_OPENCOUNT,SEEK_SET);
185: if(write(file,str2,3)!=3) {
186: close(file);
187: errormsg(WHERE,ERR_WRITE,str1,3);
1.1.1.2 ! root 188: return;
! 189: }
1.1 root 190: close(file);
191: /*****************************************/
192: /* Removing transaction from BACKOUT.DAB */
193: /*****************************************/
194: sprintf(str1,"%sbackout.dab",cfg.node_dir);
195: if(flength(str1)<1L) /* file is not there or empty */
196: return;
197: if((file=nopen(str1,O_RDONLY))==-1) {
198: errormsg(WHERE,ERR_OPEN,str1,O_RDONLY);
1.1.1.2 ! root 199: return;
! 200: }
! 201: length=(long)filelength(file);
1.1 root 202: if((buf=(char *)malloc(length))==NULL) {
203: close(file);
204: errormsg(WHERE,ERR_ALLOC,str1,length);
1.1.1.2 ! root 205: return;
! 206: }
1.1 root 207: if(read(file,buf,length)!=length) {
208: close(file);
209: free(buf);
210: errormsg(WHERE,ERR_READ,str1,length);
1.1.1.2 ! root 211: return;
! 212: }
1.1 root 213: close(file);
214: if((file=nopen(str1,O_WRONLY|O_TRUNC))==-1) {
215: errormsg(WHERE,ERR_OPEN,str1,O_WRONLY|O_TRUNC);
1.1.1.2 ! root 216: return;
! 217: }
1.1 root 218: ch=0; /* 'ch' is a 'file already removed' flag */
219: for(l=0;l<length;l+=BO_LEN) { /* in case file is in backout.dab > 1 */
220: if(!ch && buf[l]==BO_OPENFILE) {
221: memcpy(str1,buf+l+1,8);
222: str1[8]=0;
223: memcpy(&offset,buf+l+9,4);
224: if(!stricmp(str1,cfg.dir[f->dir]->code) && offset==f->datoffset) {
225: ch=1;
1.1.1.2 ! root 226: continue;
! 227: }
! 228: }
! 229: write(file,buf+l,BO_LEN);
! 230: }
1.1 root 231: free(buf);
232: close(file);
233: }
234:
235: /****************************************************************************/
236: /* Prompts user for file specification. <CR> is *.* and .* is assumed. */
237: /* Returns padded file specification. */
238: /* Returns NULL if input was aborted. */
239: /****************************************************************************/
240: char * sbbs_t::getfilespec(char *str)
241: {
242: bputs(text[FileSpecStarDotStar]);
243: if(!getstr(str,64,K_NONE))
244: strcpy(str,ALLFILES);
245: #if 0
246: else if(!strchr(str,'.') && strlen(str)<=8)
247: strcat(str,".*");
248: #endif
249: if(sys_status&SS_ABORT)
250: return(0);
251: return(str);
252: }
253:
254: /****************************************************************************/
255: /* Checks to see if filename matches filespec. Returns 1 if yes, 0 if no */
256: /****************************************************************************/
1.1.1.2 ! root 257: extern "C" BOOL filematch(const char *filename, const char *filespec)
1.1 root 258: {
259: char c;
260:
261: for(c=0;c<8;c++) /* Handle Name */
262: if(filespec[c]=='*') break;
263: else if(filespec[c]=='?') continue;
264: else if(toupper(filename[c])!=toupper(filespec[c])) return(FALSE);
265: if(filespec[8]==' ') /* no extension specified */
266: return(TRUE);
267: for(c=9;c<12;c++)
268: if(filespec[c]=='*') break;
269: else if(filespec[c]=='?') continue;
270: else if(toupper(filename[c])!=toupper(filespec[c])) return(FALSE);
271: return(TRUE);
272: }
273:
274: /*****************************************************************************/
275: /* Checks the filename 'fname' for invalid symbol or character sequences */
276: /*****************************************************************************/
277: bool sbbs_t::checkfname(char *fname)
278: {
279: int c=0,d;
280:
281: if(fname[0]=='-'
282: || strcspn(fname,ILLEGAL_FILENAME_CHARS)!=strlen(fname)) {
1.1.1.2 ! root 283: lprintf(LOG_WARNING,"Suspicious filename attempt: '%s'",fname);
! 284: hacklog("Filename", fname);
1.1 root 285: return(false);
286: }
287: if(strstr(fname,".."))
288: return(false);
289: #if 0 /* long file name support */
290: if(strcspn(fname,".")>8)
291: return(false);
292: #endif
293: d=strlen(fname);
294: while(c<d) {
295: if(fname[c]<=' ' || fname[c]&0x80)
296: return(false);
297: c++;
298: }
299: return(true);
300: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.