Annotation of sbbs/src/sbbs3/file.cpp, revision 1.1.1.2

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.