Annotation of sbbs/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.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: }

unix.superglobalmegacorp.com

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