Annotation of sbbs/sbbs3/file.cpp, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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