|
|
1.1 ! root 1: /* file.cpp */ ! 2: ! 3: /* Synchronet file transfer-related functions */ ! 4: ! 5: /* $Id: file.cpp,v 1.21 2005/09/20 03:39:51 deuce 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 2005 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: /* 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) ! 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) ! 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); ! 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]); ! 225: if(!getstr(str,64,K_NONE)) ! 226: strcpy(str,ALLFILES); ! 227: #if 0 ! 228: else if(!strchr(str,'.') && strlen(str)<=8) ! 229: strcat(str,".*"); ! 230: #endif ! 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: /****************************************************************************/ ! 239: extern "C" BOOL filematch(char *filename, char *filespec) ! 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); ! 247: if(filespec[8]==' ') /* no extension specified */ ! 248: return(TRUE); ! 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: ! 264: if(fname[0]=='-' ! 265: || strcspn(fname,ILLEGAL_FILENAME_CHARS)!=strlen(fname)) { ! 266: SAFEPRINTF(str,"Suspicious filename attempt: '%s'",fname); ! 267: errorlog(str); ! 268: return(false); ! 269: } ! 270: if(strstr(fname,"..")) ! 271: return(false); ! 272: #if 0 /* long file name support */ ! 273: if(strcspn(fname,".")>8) ! 274: return(false); ! 275: #endif ! 276: d=strlen(fname); ! 277: while(c<d) { ! 278: if(fname[c]<=' ' || fname[c]&0x80) ! 279: return(false); ! 280: c++; ! 281: } ! 282: return(true); ! 283: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.