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