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