Annotation of sbbs/sbbs3/userdat.c, revision 1.1

1.1     ! root        1: /* userdat.c */
        !             2: 
        !             3: /* Synchronet user data-related routines (exported) */
        !             4: 
        !             5: /* $Id: userdat.c,v 1.10 2000/12/05 19:06:41 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: #include "cmdshell.h"
        !            40: 
        !            41: /* convenient space-saving global variables */
        !            42: char* crlf="\r\n";
        !            43: char* nulstr="";
        !            44: 
        !            45: /****************************************************************************/
        !            46: /* Looks for a perfect match amoung all usernames (not deleted users)          */
        !            47: /* Makes dots and underscores synomynous with spaces for comparisions          */
        !            48: /* Returns the number of the perfect matched username or 0 if no match         */
        !            49: /****************************************************************************/
        !            50: uint DLLCALL matchuser(scfg_t* cfg, char *name)
        !            51: {
        !            52:        int file;
        !            53:        char str[256],c;
        !            54:        ulong l,length;
        !            55:        FILE *stream;
        !            56: 
        !            57:        sprintf(str,"%suser/name.dat",cfg->data_dir);
        !            58:        if((file=nopen(str,O_RDONLY))==-1)
        !            59:                return(0);
        !            60:        length=filelength(file);
        !            61:        if((stream=fdopen(file,"rb"))==NULL)
        !            62:                return(0);
        !            63:        for(l=0;l<length;l+=LEN_ALIAS+2) {
        !            64:                fread(str,LEN_ALIAS+2,1,stream);
        !            65:                for(c=0;c<LEN_ALIAS;c++)
        !            66:                        if(str[c]==ETX) break;
        !            67:                str[c]=0;
        !            68:                if(!stricmp(str,name)) 
        !            69:                        break;
        !            70:                /* convert dots to spaces */
        !            71:                for(c=0;str[c];c++)
        !            72:                        if(str[c]=='.') 
        !            73:                                str[c]=' ';
        !            74:                if(!stricmp(str,name)) 
        !            75:                        break;
        !            76:                /* convert spaces to dots */
        !            77:                for(c=0;str[c];c++)
        !            78:                        if(str[c]==' ') 
        !            79:                                str[c]='.';
        !            80:                if(!stricmp(str,name)) 
        !            81:                        break;
        !            82:                /* convert dots to underscores */
        !            83:                for(c=0;str[c];c++)
        !            84:                        if(str[c]=='.') 
        !            85:                                str[c]='_';
        !            86:                if(!stricmp(str,name)) 
        !            87:                        break;
        !            88:                /* convert underscores to spaces */
        !            89:                for(c=0;str[c];c++)
        !            90:                        if(str[c]=='_') 
        !            91:                                str[c]=' ';
        !            92:                if(!stricmp(str,name)) 
        !            93:                        break;
        !            94:        }
        !            95:        fclose(stream);
        !            96:        if(l<length)
        !            97:                return((l/(LEN_ALIAS+2))+1); 
        !            98:        return(0);
        !            99: }
        !           100: 
        !           101: /****************************************************************************/
        !           102: /* Returns the number of the last user in user.dat (deleted ones too)          */
        !           103: /****************************************************************************/
        !           104: uint DLLCALL lastuser(scfg_t* cfg)
        !           105: {
        !           106:        char str[256];
        !           107:        long length;
        !           108: 
        !           109:        sprintf(str,"%suser/user.dat", cfg->data_dir);
        !           110:        if((length=flength(str))>0)
        !           111:                return((uint)(length/U_LEN));
        !           112:        return(0);
        !           113: }
        !           114: 
        !           115: /****************************************************************************/
        !           116: /* Fills the structure 'user' with info for user.number        from user.dat           */
        !           117: /* Called from functions useredit, waitforcall and main_sec                                    */
        !           118: /****************************************************************************/
        !           119: int DLLCALL getuserdat(scfg_t* cfg, user_t *user)
        !           120: {
        !           121:        char userdat[U_LEN+1],str[U_LEN+1],tmp[64];
        !           122:        int i,file;
        !           123: 
        !           124:        if(!user->number || user->number>lastuser(cfg)) {
        !           125:                memset(user,0,sizeof(user_t));
        !           126:                return(-1); 
        !           127:        }
        !           128:        sprintf(userdat,"%suser/user.dat",cfg->data_dir);
        !           129:        if((file=nopen(userdat,O_RDONLY|O_DENYNONE))==-1) {
        !           130:                memset(user,0,sizeof(user_t));
        !           131:                return(errno); 
        !           132:        }
        !           133:        lseek(file,(long)((long)(user->number-1)*U_LEN),SEEK_SET);
        !           134:        i=0;
        !           135:        while(i<LOOP_NODEDAB
        !           136:                && lock(file,(long)((long)(user->number-1)*U_LEN),U_LEN)==-1) {
        !           137:                if(i>10)
        !           138:                        mswait(55);
        !           139:                i++; 
        !           140:        }
        !           141: 
        !           142:        if(i>=LOOP_NODEDAB) {
        !           143:                close(file);
        !           144:                memset(user,0L,sizeof(user_t));
        !           145:                return(-2); 
        !           146:        }
        !           147: 
        !           148:        if(read(file,userdat,U_LEN)!=U_LEN) {
        !           149:                unlock(file,(long)((long)(user->number-1)*U_LEN),U_LEN);
        !           150:                close(file);
        !           151:                memset(user,0L,sizeof(user_t));
        !           152:                return(-3); 
        !           153:        }
        !           154: 
        !           155:        unlock(file,(long)((long)(user->number-1)*U_LEN),U_LEN);
        !           156:        close(file);
        !           157:        getrec(userdat,U_ALIAS,LEN_ALIAS,user->alias);
        !           158:        /* order of these function      */
        !           159:        getrec(userdat,U_NAME,LEN_NAME,user->name);
        !           160:        /* calls is irrelevant */
        !           161:        getrec(userdat,U_HANDLE,LEN_HANDLE,user->handle);
        !           162:        getrec(userdat,U_NOTE,LEN_NOTE,user->note);
        !           163:        getrec(userdat,U_COMP,LEN_COMP,user->comp);
        !           164:        getrec(userdat,U_COMMENT,LEN_COMMENT,user->comment);
        !           165:        getrec(userdat,U_NETMAIL,LEN_NETMAIL,user->netmail);
        !           166:        getrec(userdat,U_ADDRESS,LEN_ADDRESS,user->address);
        !           167:        getrec(userdat,U_LOCATION,LEN_LOCATION,user->location);
        !           168:        getrec(userdat,U_ZIPCODE,LEN_ZIPCODE,user->zipcode);
        !           169:        getrec(userdat,U_PASS,LEN_PASS,user->pass);
        !           170:        getrec(userdat,U_PHONE,LEN_PHONE,user->phone);
        !           171:        getrec(userdat,U_BIRTH,LEN_BIRTH,user->birth);
        !           172:        getrec(userdat,U_MODEM,LEN_MODEM,user->modem);
        !           173:        getrec(userdat,U_LASTON,8,str); user->laston=ahtoul(str);
        !           174:        getrec(userdat,U_FIRSTON,8,str); user->firston=ahtoul(str);
        !           175:        getrec(userdat,U_EXPIRE,8,str); user->expire=ahtoul(str);
        !           176:        getrec(userdat,U_PWMOD,8,str); user->pwmod=ahtoul(str);
        !           177:        getrec(userdat,U_NS_TIME,8,str);
        !           178:        user->ns_time=ahtoul(str);
        !           179:        if(user->ns_time<0x20000000L)
        !           180:                user->ns_time=user->laston;  /* Fix for v2.00->v2.10 */
        !           181: 
        !           182:        getrec(userdat,U_LOGONS,5,str); user->logons=atoi(str);
        !           183:        getrec(userdat,U_LTODAY,5,str); user->ltoday=atoi(str);
        !           184:        getrec(userdat,U_TIMEON,5,str); user->timeon=atoi(str);
        !           185:        getrec(userdat,U_TEXTRA,5,str); user->textra=atoi(str);
        !           186:        getrec(userdat,U_TTODAY,5,str); user->ttoday=atoi(str);
        !           187:        getrec(userdat,U_TLAST,5,str); user->tlast=atoi(str);
        !           188:        getrec(userdat,U_POSTS,5,str); user->posts=atoi(str);
        !           189:        getrec(userdat,U_EMAILS,5,str); user->emails=atoi(str);
        !           190:        getrec(userdat,U_FBACKS,5,str); user->fbacks=atoi(str);
        !           191:        getrec(userdat,U_ETODAY,5,str); user->etoday=atoi(str);
        !           192:        getrec(userdat,U_PTODAY,5,str); user->ptoday=atoi(str);
        !           193:        getrec(userdat,U_ULB,10,str); user->ulb=atol(str);
        !           194:        getrec(userdat,U_ULS,5,str); user->uls=atoi(str);
        !           195:        getrec(userdat,U_DLB,10,str); user->dlb=atol(str);
        !           196:        getrec(userdat,U_DLS,5,str); user->dls=atoi(str);
        !           197:        getrec(userdat,U_CDT,10,str); user->cdt=atol(str);
        !           198:        getrec(userdat,U_MIN,10,str); user->min=atol(str);
        !           199:        getrec(userdat,U_LEVEL,2,str); user->level=atoi(str);
        !           200:        getrec(userdat,U_FLAGS1,8,str); user->flags1=ahtoul(str); /***
        !           201:        getrec(userdat,U_TL,2,str); user->tl=atoi(str); ***/
        !           202:        getrec(userdat,U_FLAGS2,8,str); user->flags2=ahtoul(str);
        !           203:        getrec(userdat,U_FLAGS3,8,str); user->flags3=ahtoul(str);
        !           204:        getrec(userdat,U_FLAGS4,8,str); user->flags4=ahtoul(str);
        !           205:        getrec(userdat,U_EXEMPT,8,str); user->exempt=ahtoul(str);
        !           206:        getrec(userdat,U_REST,8,str); user->rest=ahtoul(str);
        !           207:        getrec(userdat,U_ROWS,2,str); user->rows=atoi(str);
        !           208:        if(user->rows && user->rows<10)
        !           209:                user->rows=10;
        !           210:        user->sex=userdat[U_SEX];
        !           211:        if(!user->sex)
        !           212:                user->sex=SP;    /* fix for v1b04 that could save as 0 */
        !           213:        user->prot=userdat[U_PROT];
        !           214:        if(user->prot<SP)
        !           215:                user->prot=SP;
        !           216:        getrec(userdat,U_MISC,8,str); user->misc=ahtoul(str);
        !           217:        if(user->rest&FLAG('Q'))
        !           218:                user->misc&=~SPIN;
        !           219: 
        !           220:        getrec(userdat,U_LEECH,2,str);
        !           221:        user->leech=(uchar)ahtoul(str);
        !           222:        getrec(userdat,U_CURSUB,8,user->cursub);        /* was useron.cursub (01/19/00) */
        !           223:        getrec(userdat,U_CURDIR,8,user->curdir);        /* was useron.curdir (01/19/00) */
        !           224: 
        !           225:        getrec(userdat,U_FREECDT,10,str);
        !           226:        user->freecdt=atol(str);
        !           227: 
        !           228:        getrec(userdat,U_XEDIT,8,str);
        !           229:        for(i=0;i<cfg->total_xedits;i++)
        !           230:                if(!stricmp(str,cfg->xedit[i]->code) /* && chk_ar(cfg->xedit[i]->ar,user) */)
        !           231:                        break;
        !           232:        user->xedit=i+1;
        !           233:        if(user->xedit>cfg->total_xedits)
        !           234:                user->xedit=0;
        !           235: 
        !           236:        getrec(userdat,U_SHELL,8,str);
        !           237:        for(i=0;i<cfg->total_shells;i++)
        !           238:                if(!stricmp(str,cfg->shell[i]->code))
        !           239:                        break;
        !           240:        if(i==cfg->total_shells)
        !           241:                i=0;
        !           242:        user->shell=i;
        !           243: 
        !           244:        getrec(userdat,U_QWK,8,str);
        !           245:        if(str[0]<SP) {                            /* v1c, so set defaults */
        !           246:                if(user->rest&FLAG('Q'))
        !           247:                        user->qwk=(QWK_RETCTLA);
        !           248:                else
        !           249:                        user->qwk=(QWK_FILES|QWK_ATTACH|QWK_EMAIL|QWK_DELMAIL); }
        !           250:        else
        !           251:                user->qwk=ahtoul(str);
        !           252: 
        !           253:        getrec(userdat,U_TMPEXT,3,user->tmpext);
        !           254:        if((!user->tmpext[0] || !strcmp(user->tmpext,"0")) && cfg->total_fcomps)
        !           255:                strcpy(user->tmpext,cfg->fcomp[0]->ext);  /* For v1x to v2x conversion */
        !           256: 
        !           257:        getrec(userdat,U_CHAT,8,str);
        !           258:        user->chat=ahtoul(str);
        !           259: 
        !           260:        unixtodstr(cfg, time(NULL),str);
        !           261:        unixtodstr(cfg, user->laston,tmp);
        !           262:        if(strcmp(str,tmp) && user->ltoday) {
        !           263:                user->ltoday=user->ttoday=user->ptoday=user->etoday=user->textra=0;
        !           264:                user->freecdt=cfg->level_freecdtperday[user->level];
        !           265:        }
        !           266: 
        !           267: 
        !           268: #if 0 // removed 01/19/00
        !           269:        if(useron.number==user->number) {
        !           270:                if(user!=&useron)
        !           271:                        useron=*user;
        !           272: 
        !           273:                if(online) {
        !           274: 
        !           275:        #if 0   /* legacy? */
        !           276:                        getusrdirs();
        !           277:                        getusrsubs();
        !           278:        #endif
        !           279:                        if(user->misc&AUTOTERM) {                       // was useron.misc (01/19/00)
        !           280:                                user->misc&=~(ANSI|RIP|WIP);
        !           281:                                user->misc|=autoterm; }
        !           282:                } }
        !           283: #endif
        !           284:        return(0);
        !           285: }
        !           286: 
        !           287: /****************************************************************************/
        !           288: /* Writes into user.number's slot in user.dat data in structure 'user'      */
        !           289: /* Called from functions newuser, useredit and main                         */
        !           290: /****************************************************************************/
        !           291: int DLLCALL putuserdat(scfg_t* cfg, user_t* user)
        !           292: {
        !           293:     int i,file;
        !           294:     char userdat[U_LEN+1],str[U_LEN+1];
        !           295:     node_t node;
        !           296: 
        !           297:        if(!user->number) 
        !           298:                return(-1); 
        !           299: 
        !           300:        memset(userdat,ETX,U_LEN);
        !           301:        putrec(userdat,U_ALIAS,LEN_ALIAS+5,user->alias);
        !           302:        putrec(userdat,U_NAME,LEN_NAME,user->name);
        !           303:        putrec(userdat,U_HANDLE,LEN_HANDLE,user->handle);
        !           304:        putrec(userdat,U_HANDLE+LEN_HANDLE,2,crlf);
        !           305: 
        !           306:        putrec(userdat,U_NOTE,LEN_NOTE,user->note);
        !           307:        putrec(userdat,U_COMP,LEN_COMP,user->comp);
        !           308:        putrec(userdat,U_COMP+LEN_COMP,2,crlf);
        !           309: 
        !           310:        putrec(userdat,U_COMMENT,LEN_COMMENT,user->comment);
        !           311:        putrec(userdat,U_COMMENT+LEN_COMMENT,2,crlf);
        !           312: 
        !           313:        putrec(userdat,U_NETMAIL,LEN_NETMAIL,user->netmail);
        !           314:        putrec(userdat,U_NETMAIL+LEN_NETMAIL,2,crlf);
        !           315: 
        !           316:        putrec(userdat,U_ADDRESS,LEN_ADDRESS,user->address);
        !           317:        putrec(userdat,U_LOCATION,LEN_LOCATION,user->location);
        !           318:        putrec(userdat,U_ZIPCODE,LEN_ZIPCODE,user->zipcode);
        !           319:        putrec(userdat,U_ZIPCODE+LEN_ZIPCODE,2,crlf);
        !           320: 
        !           321:        putrec(userdat,U_PASS,LEN_PASS,user->pass);
        !           322:        putrec(userdat,U_PHONE,LEN_PHONE,user->phone);
        !           323:        putrec(userdat,U_BIRTH,LEN_BIRTH,user->birth);
        !           324:        putrec(userdat,U_MODEM,LEN_MODEM,user->modem);
        !           325:        putrec(userdat,U_LASTON,8,ultoa(user->laston,str,16));
        !           326:        putrec(userdat,U_FIRSTON,8,ultoa(user->firston,str,16));
        !           327:        putrec(userdat,U_EXPIRE,8,ultoa(user->expire,str,16));
        !           328:        putrec(userdat,U_PWMOD,8,ultoa(user->pwmod,str,16));
        !           329:        putrec(userdat,U_PWMOD+8,2,crlf);
        !           330: 
        !           331:        putrec(userdat,U_LOGONS,5,ultoa(user->logons,str,10));
        !           332:        putrec(userdat,U_LTODAY,5,ultoa(user->ltoday,str,10));
        !           333:        putrec(userdat,U_TIMEON,5,ultoa(user->timeon,str,10));
        !           334:        putrec(userdat,U_TEXTRA,5,ultoa(user->textra,str,10));
        !           335:        putrec(userdat,U_TTODAY,5,ultoa(user->ttoday,str,10));
        !           336:        putrec(userdat,U_TLAST,5,ultoa(user->tlast,str,10));
        !           337:        putrec(userdat,U_POSTS,5,ultoa(user->posts,str,10));
        !           338:        putrec(userdat,U_EMAILS,5,ultoa(user->emails,str,10));
        !           339:        putrec(userdat,U_FBACKS,5,ultoa(user->fbacks,str,10));
        !           340:        putrec(userdat,U_ETODAY,5,ultoa(user->etoday,str,10));
        !           341:        putrec(userdat,U_PTODAY,5,ultoa(user->ptoday,str,10));
        !           342:        putrec(userdat,U_PTODAY+5,2,crlf);
        !           343: 
        !           344:        putrec(userdat,U_ULB,10,ultoa(user->ulb,str,10));
        !           345:        putrec(userdat,U_ULS,5,ultoa(user->uls,str,10));
        !           346:        putrec(userdat,U_DLB,10,ultoa(user->dlb,str,10));
        !           347:        putrec(userdat,U_DLS,5,ultoa(user->dls,str,10));
        !           348:        putrec(userdat,U_CDT,10,ultoa(user->cdt,str,10));
        !           349:        putrec(userdat,U_MIN,10,ultoa(user->min,str,10));
        !           350:        putrec(userdat,U_MIN+10,2,crlf);
        !           351: 
        !           352:        putrec(userdat,U_LEVEL,2,ultoa(user->level,str,10));
        !           353:        putrec(userdat,U_FLAGS1,8,ultoa(user->flags1,str,16));
        !           354:        putrec(userdat,U_TL,2,nulstr);  /* unused */
        !           355:        putrec(userdat,U_FLAGS2,8,ultoa(user->flags2,str,16));
        !           356:        putrec(userdat,U_EXEMPT,8,ultoa(user->exempt,str,16));
        !           357:        putrec(userdat,U_REST,8,ultoa(user->rest,str,16));
        !           358:        putrec(userdat,U_REST+8,2,crlf);
        !           359: 
        !           360:        putrec(userdat,U_ROWS,2,ultoa(user->rows,str,10));
        !           361:        userdat[U_SEX]=user->sex;
        !           362:        userdat[U_PROT]=user->prot;
        !           363:        putrec(userdat,U_MISC,8,ultoa(user->misc,str,16));
        !           364:        putrec(userdat,U_LEECH,2,ultoa(user->leech,str,16));
        !           365: 
        !           366:        putrec(userdat,U_CURSUB,8,user->cursub);
        !           367:        putrec(userdat,U_CURDIR,8,user->curdir);
        !           368: 
        !           369:        // putrec(userdat,U_CMDSET,2,ultoa(user->cmdset,str,16)); /* Unused */
        !           370:        putrec(userdat,U_CMDSET+2,2,crlf);
        !           371: 
        !           372:        putrec(userdat,U_XFER_CMD+LEN_XFER_CMD,2,crlf);
        !           373: 
        !           374:        putrec(userdat,U_MAIL_CMD+LEN_MAIL_CMD,2,crlf);
        !           375: 
        !           376:        putrec(userdat,U_FREECDT,10,ultoa(user->freecdt,str,10));
        !           377: 
        !           378:        putrec(userdat,U_FLAGS3,8,ultoa(user->flags3,str,16));
        !           379:        putrec(userdat,U_FLAGS4,8,ultoa(user->flags4,str,16));
        !           380: 
        !           381:        if(user->xedit)
        !           382:                putrec(userdat,U_XEDIT,8,cfg->xedit[user->xedit-1]->code);
        !           383:        else
        !           384:                putrec(userdat,U_XEDIT,8,nulstr);
        !           385: 
        !           386:        putrec(userdat,U_SHELL,8,cfg->shell[user->shell]->code);
        !           387: 
        !           388:        putrec(userdat,U_QWK,8,ultoa(user->qwk,str,16));
        !           389:        putrec(userdat,U_TMPEXT,3,user->tmpext);
        !           390:        putrec(userdat,U_CHAT,8,ultoa(user->chat,str,16));
        !           391:        putrec(userdat,U_NS_TIME,8,ultoa(user->ns_time,str,16));
        !           392: 
        !           393:        putrec(userdat,U_UNUSED,29,crlf);
        !           394:        putrec(userdat,U_UNUSED+29,2,crlf);
        !           395: 
        !           396:        sprintf(str,"%suser/user.dat", cfg->data_dir);
        !           397:        if((file=nopen(str,O_WRONLY|O_CREAT|O_DENYNONE))==-1) {
        !           398:                return(errno);
        !           399:        }
        !           400: 
        !           401:        lseek(file,(long)((long)((long)user->number-1)*U_LEN),SEEK_SET);
        !           402: 
        !           403:        i=0;
        !           404:        while(i<LOOP_NODEDAB
        !           405:                && lock(file,(long)((long)(user->number-1)*U_LEN),U_LEN)==-1) {
        !           406:                if(i>10)
        !           407:                        mswait(55);
        !           408:                i++; 
        !           409:        }
        !           410: 
        !           411:        if(i>=LOOP_NODEDAB) {
        !           412:                close(file);
        !           413:                return(-2); 
        !           414:        }
        !           415: 
        !           416:        if(write(file,userdat,U_LEN)!=U_LEN) {
        !           417:                unlock(file,(long)((long)(user->number-1)*U_LEN),U_LEN);
        !           418:                close(file);
        !           419:                return(-3); 
        !           420:        }
        !           421:        unlock(file,(long)((long)(user->number-1)*U_LEN),U_LEN);
        !           422:        close(file);
        !           423:        for(i=1;i<=cfg->sys_nodes;i++) { /* instant user data update */
        !           424:                if(i==cfg->node_num)
        !           425:                        continue;
        !           426:                getnodedat(cfg, i,&node,0);
        !           427:                if(node.useron==user->number && (node.status==NODE_INUSE
        !           428:                        || node.status==NODE_QUIET)) {
        !           429:                        getnodedat(cfg, i,&node,1);
        !           430:                        node.misc|=NODE_UDAT;
        !           431:                        putnodedat(cfg, i,&node);
        !           432:                        break; 
        !           433:                } 
        !           434:        }
        !           435:        return(0);
        !           436: }
        !           437: 
        !           438: 
        !           439: /****************************************************************************/
        !           440: /* Returns the username in 'str' that corresponds to the 'usernumber'       */
        !           441: /* Called from functions everywhere                                         */
        !           442: /****************************************************************************/
        !           443: char* DLLCALL username(scfg_t* cfg, int usernumber,char *strin)
        !           444: {
        !           445:     char str[256];
        !           446:     char c;
        !           447:     int file;
        !           448: 
        !           449:        if(usernumber<1) {
        !           450:                strin[0]=0;
        !           451:                return(strin); }
        !           452:        sprintf(str,"%suser/name.dat",cfg->data_dir);
        !           453:        if(flength(str)<1L) {
        !           454:                strin[0]=0;
        !           455:                return(strin); }
        !           456:        if((file=nopen(str,O_RDONLY))==-1) {
        !           457:                strin[0]=0;
        !           458:                return(strin); }
        !           459:        if(filelength(file)<(long)((long)usernumber*(LEN_ALIAS+2))) {
        !           460:                close(file);
        !           461:                strin[0]=0;
        !           462:                return(strin); }
        !           463:        lseek(file,(long)((long)(usernumber-1)*(LEN_ALIAS+2)),SEEK_SET);
        !           464:        read(file,strin,LEN_ALIAS);
        !           465:        close(file);
        !           466:        for(c=0;c<LEN_ALIAS;c++)
        !           467:                if(strin[c]==ETX) break;
        !           468:        strin[c]=0;
        !           469:        if(!c)
        !           470:                strcpy(strin,"DELETED USER");
        !           471:        return(strin);
        !           472: }
        !           473: 
        !           474: /****************************************************************************/
        !           475: /* Places into 'strout' CR or ETX terminated string starting at             */
        !           476: /* 'start' and ending at 'start'+'length' or terminator from 'strin'        */
        !           477: /****************************************************************************/
        !           478: void DLLCALL getrec(char *strin,int start,int length,char *strout)
        !           479: {
        !           480:     int i=0,stop;
        !           481: 
        !           482:        stop=start+length;
        !           483:        while(start<stop) {
        !           484:                if(strin[start]==ETX || strin[start]==CR || strin[start]==LF)
        !           485:                        break;
        !           486:                strout[i++]=strin[start++]; 
        !           487:        }
        !           488:        strout[i]=0;
        !           489: }
        !           490: 
        !           491: /****************************************************************************/
        !           492: /* Places into 'strout', 'strin' starting at 'start' and ending at          */
        !           493: /* 'start'+'length'                                                         */
        !           494: /****************************************************************************/
        !           495: void DLLCALL putrec(char *strout,int start,int length,char *strin)
        !           496: {
        !           497:     int i=0,j;
        !           498: 
        !           499:        j=strlen(strin);
        !           500:        while(i<j && i<length)
        !           501:                strout[start++]=strin[i++];
        !           502:        while(i++<length)
        !           503:                strout[start++]=ETX;
        !           504: }
        !           505: 
        !           506: 
        !           507: /****************************************************************************/
        !           508: /* Returns the age derived from the string 'birth' in the format MM/DD/YY      */
        !           509: /* Called from functions statusline, main_sec, xfer_sec, useredit and          */
        !           510: /* text files                                                                                                                          */
        !           511: /****************************************************************************/
        !           512: char DLLCALL getage(scfg_t* cfg, char *birth)
        !           513: {
        !           514:        char    age;
        !           515:        struct  tm * tm;
        !           516:        time_t  now;
        !           517: 
        !           518:        if(!atoi(birth) || !atoi(birth+3))      /* Invalid */
        !           519:                return(0);
        !           520: 
        !           521:        now=time(NULL);
        !           522:        tm=gmtime(&now);
        !           523:        if(tm==NULL)
        !           524:                return(0);
        !           525:        age=(tm->tm_year)-(((birth[6]&0xf)*10)+(birth[7]&0xf));
        !           526:        if(age>105)
        !           527:                age-=105;
        !           528:        tm->tm_mon++;   /* convert to 1 based */
        !           529:        if(cfg->sys_misc&SM_EURODATE) {         /* DD/MM/YY format */
        !           530:                if(atoi(birth)>31 || atoi(birth+3)>12)
        !           531:                        return(0);
        !           532:                if(((birth[3]&0xf)*10)+(birth[4]&0xf)>tm->tm_mon ||
        !           533:                        (((birth[3]&0xf)*10)+(birth[4]&0xf)==tm->tm_mon &&
        !           534:                        ((birth[0]&0xf)*10)+(birth[1]&0xf)>tm->tm_mday))
        !           535:                        age--; }
        !           536:        else {                                                  /* MM/DD/YY format */
        !           537:                if(atoi(birth)>12 || atoi(birth+3)>31)
        !           538:                        return(0);
        !           539:                if(((birth[0]&0xf)*10)+(birth[1]&0xf)>tm->tm_mon ||
        !           540:                        (((birth[0]&0xf)*10)+(birth[1]&0xf)==tm->tm_mon &&
        !           541:                        ((birth[3]&0xf)*10)+(birth[4]&0xf)>tm->tm_mday))
        !           542:                        age--; }
        !           543:        if(age<0)
        !           544:                return(0);
        !           545:        return(age);
        !           546: }
        !           547: 
        !           548: 
        !           549: /****************************************************************************/
        !           550: /* Reads the data for node number 'number' into the structure 'node'        */
        !           551: /* from node.dab                                                                                                                       */
        !           552: /* if lockit is non-zero, locks this node's record. putnodedat() unlocks it */
        !           553: /****************************************************************************/
        !           554: int DLLCALL getnodedat(scfg_t* cfg, uint number, node_t *node, char lockit)
        !           555: {
        !           556:        char str[256];
        !           557:        int count=0;
        !           558:        int file;
        !           559: 
        !           560:        if(!number || number>cfg->sys_nodes)
        !           561:                return(-1);
        !           562: 
        !           563:        sprintf(str,"%snode.dab",cfg->ctrl_dir);
        !           564:        if((file=nopen(str,O_RDONLY|O_DENYNONE))==-1) {
        !           565:                memset(node,0,sizeof(node_t));
        !           566:                return(errno); 
        !           567:        }
        !           568: 
        !           569:        number--;       /* make zero based */
        !           570:        while(count<LOOP_NODEDAB) {
        !           571:                if(count>10)
        !           572:                        mswait(100);
        !           573:                lseek(file,(long)number*sizeof(node_t),SEEK_SET);
        !           574:                if(lockit
        !           575:                        && lock(file,(long)number*sizeof(node_t),sizeof(node_t))==-1) {
        !           576:                        count++;
        !           577:                        continue; }
        !           578:                if(read(file,node,sizeof(node_t))==sizeof(node_t))
        !           579:                        break;
        !           580:                count++; }
        !           581: 
        !           582:        close(file);
        !           583:        if(count==LOOP_NODEDAB) 
        !           584:                return(-2); 
        !           585:        
        !           586:        return(0);
        !           587: }
        !           588: 
        !           589: /****************************************************************************/
        !           590: /* Write the data from the structure 'node' into node.dab                                      */
        !           591: /* getnodedat(num,&node,1); must have been called before calling this func  */
        !           592: /*          NOTE: ------^   the indicates the node record has been locked   */
        !           593: /****************************************************************************/
        !           594: int DLLCALL putnodedat(scfg_t* cfg, uint number, node_t* node)
        !           595: {
        !           596:        char str[256];
        !           597:        int file;
        !           598: 
        !           599:        if(!number || number>cfg->sys_nodes) 
        !           600:                return(-1);
        !           601: 
        !           602:        sprintf(str,"%snode.dab",cfg->ctrl_dir);
        !           603:        if((file=nopen(str,O_RDWR|O_CREAT|O_DENYNONE))==-1) {
        !           604:                memset(node,0,sizeof(node_t));
        !           605:                return(errno); 
        !           606:        }
        !           607: 
        !           608:        number--;       /* make zero based */
        !           609:        lseek(file,(long)number*sizeof(node_t),SEEK_SET);
        !           610:        if(write(file,node,sizeof(node_t))!=sizeof(node_t)) {
        !           611:                unlock(file,(long)number*sizeof(node_t),sizeof(node_t));
        !           612:                close(file);
        !           613:                return(-2); 
        !           614:        }
        !           615:        unlock(file,(long)number*sizeof(node_t),sizeof(node_t));
        !           616:        close(file);
        !           617: 
        !           618:        return(0);
        !           619: }
        !           620: 
        !           621: /****************************************************************************/
        !           622: uint DLLCALL userdatdupe(scfg_t* cfg, uint usernumber, uint offset, uint datlen, char *dat
        !           623:     ,BOOL del)
        !           624: {
        !           625:     char       str[256];
        !           626:     uint       i;
        !           627:        int             file;
        !           628:     long       l,length;
        !           629: 
        !           630:        truncsp(dat);
        !           631:        sprintf(str,"%suser/user.dat", cfg->data_dir);
        !           632:        if((file=nopen(str,O_RDONLY|O_DENYNONE))==-1)
        !           633:                return(0);
        !           634:        length=filelength(file);
        !           635:        for(l=0;l<length;l+=U_LEN) {
        !           636:                if(usernumber && l/U_LEN==(long)usernumber-1)
        !           637:                        continue;
        !           638:                lseek(file,l+offset,SEEK_SET);
        !           639:                i=0;
        !           640:                while(i<LOOP_NODEDAB && lock(file,l,U_LEN)==-1) {
        !           641:                        if(i>10)
        !           642:                                mswait(55);
        !           643:                        i++; }
        !           644: 
        !           645:                if(i>=LOOP_NODEDAB) {
        !           646:                        close(file);
        !           647:                        return(0); }
        !           648: 
        !           649:                read(file,str,datlen);
        !           650:                for(i=0;i<datlen;i++)
        !           651:                        if(str[i]==ETX) break;
        !           652:                str[i]=0;
        !           653:                truncsp(str);
        !           654:                if(!stricmp(str,dat)) {
        !           655:                        if(!del) {      /* Don't include deleted users in search */
        !           656:                                lseek(file,l+U_MISC,SEEK_SET);
        !           657:                                read(file,str,8);
        !           658:                                getrec(str,0,8,str);
        !           659:                                if(ahtoul(str)&(DELETED|INACTIVE)) {
        !           660:                                        unlock(file,l,U_LEN);
        !           661:                                        continue; } }
        !           662:                        unlock(file,l,U_LEN);
        !           663:                        close(file);
        !           664:                        return((l/U_LEN)+1); }
        !           665:                else
        !           666:                        unlock(file,l,U_LEN); }
        !           667:        close(file);
        !           668:        return(0);
        !           669: }
        !           670: 
        !           671: /****************************************************************************/
        !           672: /* Creates a short message for 'usernumber' than contains 'strin'           */
        !           673: /****************************************************************************/
        !           674: int DLLCALL putsmsg(scfg_t* cfg, int usernumber, char *strin)
        !           675: {
        !           676:     char str[256];
        !           677:     int file,i;
        !           678:     node_t node;
        !           679: 
        !           680:        sprintf(str,"%smsgs/%4.4u.msg",cfg->data_dir,usernumber);
        !           681:        if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) {
        !           682:                return(errno); 
        !           683:        }
        !           684:        i=strlen(strin);
        !           685:        if(write(file,strin,i)!=i) {
        !           686:                close(file);
        !           687:                return(errno); 
        !           688:        }
        !           689:        close(file);
        !           690:        for(i=1;i<=cfg->sys_nodes;i++) {     /* flag node if user on that msg waiting */
        !           691:                getnodedat(cfg,i,&node,0);
        !           692:                if(node.useron==usernumber
        !           693:                        && (node.status==NODE_INUSE || node.status==NODE_QUIET)
        !           694:                        && !(node.misc&NODE_MSGW)) {
        !           695:                        getnodedat(cfg,i,&node,1);
        !           696:                        node.misc|=NODE_MSGW;
        !           697:                        putnodedat(cfg,i,&node); 
        !           698:                } 
        !           699:        }
        !           700:        return(0);
        !           701: }
        !           702: 
        !           703: static BOOL ar_exp(scfg_t* cfg, uchar **ptrptr, user_t* user)
        !           704: {
        !           705:        BOOL    result,not,or,equal;
        !           706:        uint    i,n,artype=AR_LEVEL,age;
        !           707:        ulong   l;
        !           708:        time_t  now;
        !           709:        struct tm * tm;
        !           710: 
        !           711:        result = TRUE;
        !           712: 
        !           713:        for(;(**ptrptr);(*ptrptr)++) {
        !           714: 
        !           715:                if((**ptrptr)==AR_ENDNEST)
        !           716:                        break;
        !           717: 
        !           718:                not=or=equal = FALSE;
        !           719: 
        !           720:                if((**ptrptr)==AR_OR) {
        !           721:                        or=1;
        !           722:                        (*ptrptr)++; }
        !           723:                
        !           724:                if((**ptrptr)==AR_NOT) {
        !           725:                        not=1;
        !           726:                        (*ptrptr)++; }
        !           727: 
        !           728:                if((**ptrptr)==AR_EQUAL) {
        !           729:                        equal=1;
        !           730:                        (*ptrptr)++; }
        !           731: 
        !           732:                if((result && or) || (!result && !or))
        !           733:                        break;
        !           734: 
        !           735:                if((**ptrptr)==AR_BEGNEST) {
        !           736:                        (*ptrptr)++;
        !           737:                        if(ar_exp(cfg,ptrptr,user))
        !           738:                                result=!not;
        !           739:                        else
        !           740:                                result=not;
        !           741:                        while((**ptrptr)!=AR_ENDNEST && (**ptrptr)) /* in case of early exit */
        !           742:                                (*ptrptr)++;
        !           743:                        if(!(**ptrptr))
        !           744:                                break;
        !           745:                        continue; }
        !           746: 
        !           747:                artype=(**ptrptr);
        !           748:                switch(artype) {
        !           749:                        case AR_ANSI:                           /* No arguments */
        !           750:                        case AR_RIP:
        !           751:                        case AR_WIP:
        !           752:                        case AR_LOCAL:
        !           753:                        case AR_EXPERT:
        !           754:                        case AR_SYSOP:
        !           755:                        case AR_QUIET:
        !           756:                        case AR_OS2:
        !           757:                        case AR_DOS:
        !           758:                                break;
        !           759:                        default:
        !           760:                                (*ptrptr)++;
        !           761:                                break; }
        !           762: 
        !           763:                n=(**ptrptr);
        !           764:                i=(*(short *)*ptrptr);
        !           765:                switch(artype) {
        !           766:                        case AR_LEVEL:
        !           767:                                if((equal && user->level!=n) || (!equal && user->level<n))
        !           768:                                        result=not;
        !           769:                                else
        !           770:                                        result=!not;
        !           771:                                break;
        !           772:                        case AR_AGE:
        !           773:                                age=getage(cfg,user->birth);
        !           774:                                if((equal && age!=n) || (!equal && age<n))
        !           775:                                        result=not;
        !           776:                                else
        !           777:                                        result=!not;
        !           778:                                break;
        !           779:                        case AR_BPS:
        !           780:                                result=!not;
        !           781:                                (*ptrptr)++;
        !           782:                                break;
        !           783:                        case AR_ANSI:
        !           784:                                if(!(user->misc&ANSI))
        !           785:                                        result=not;
        !           786:                                else result=!not;
        !           787:                                break;
        !           788:                        case AR_RIP:
        !           789:                                if(!(user->misc&RIP))
        !           790:                                        result=not;
        !           791:                                else result=!not;
        !           792:                                break;
        !           793:                        case AR_WIP:
        !           794:                                if(!(user->misc&WIP))
        !           795:                                        result=not;
        !           796:                                else result=!not;
        !           797:                                break;
        !           798:                        case AR_OS2:
        !           799:                                #ifndef __OS2__
        !           800:                                        result=not;
        !           801:                                #else
        !           802:                                        result=!not;
        !           803:                                #endif
        !           804:                                break;
        !           805:                        case AR_DOS:
        !           806:                                #ifdef __FLAT__
        !           807:                                        result=not;
        !           808:                                #else
        !           809:                                        result=!not;
        !           810:                                #endif
        !           811:                                break;
        !           812:                        case AR_WIN32:
        !           813:                                #ifndef _WIN32
        !           814:                                        result=not;
        !           815:                                #else
        !           816:                                        result=!not;
        !           817:                                #endif
        !           818:                                break;
        !           819:                        case AR_UNIX:
        !           820:                                #ifndef __unix__
        !           821:                                        result=not;
        !           822:                                #else
        !           823:                                        result=!not;
        !           824:                                #endif
        !           825:                                break;
        !           826:                        case AR_LINUX:
        !           827:                                #ifndef __linux__
        !           828:                                        result=not;
        !           829:                                #else
        !           830:                                        result=!not;
        !           831:                                #endif
        !           832:                                break;
        !           833:                        case AR_EXPERT:
        !           834:                                if(!(user->misc&EXPERT))
        !           835:                                        result=not;
        !           836:                                else result=!not;
        !           837:                                break;
        !           838:                        case AR_SYSOP:
        !           839:                                if(user->level<SYSOP_LEVEL)
        !           840:                                        result=not;
        !           841:                                else result=!not;
        !           842:                                break;
        !           843:                        case AR_QUIET:
        !           844:                                result=not;
        !           845:                                break;
        !           846:                        case AR_LOCAL:
        !           847:                                result=not;
        !           848:                                break;
        !           849:                        case AR_DAY:
        !           850:                                now=time(NULL);
        !           851:                                tm=localtime(&now);
        !           852:                                if(tm==NULL || (equal && tm->tm_wday!=(int)n) 
        !           853:                                        || (!equal && tm->tm_wday<(int)n))
        !           854:                                        result=not;
        !           855:                                else
        !           856:                                        result=!not;
        !           857:                                break;
        !           858:                        case AR_CREDIT:
        !           859:                                l=(ulong)i*1024UL;
        !           860:                                if((equal && user->cdt+user->freecdt!=l)
        !           861:                                        || (!equal && user->cdt+user->freecdt<l))
        !           862:                                        result=not;
        !           863:                                else
        !           864:                                        result=!not;
        !           865:                                (*ptrptr)++;
        !           866:                                break;
        !           867:                        case AR_NODE:
        !           868:                                if((equal && cfg->node_num!=n) || (!equal && cfg->node_num<n))
        !           869:                                        result=not;
        !           870:                                else
        !           871:                                        result=!not;
        !           872:                                break;
        !           873:                        case AR_USER:
        !           874:                                if((equal && user->number!=i) || (!equal && user->number<i))
        !           875:                                        result=not;
        !           876:                                else
        !           877:                                        result=!not;
        !           878:                                (*ptrptr)++;
        !           879:                                break;
        !           880:                        case AR_GROUP:
        !           881:                                result=not;
        !           882:                                (*ptrptr)++;
        !           883:                                break;
        !           884:                        case AR_SUB:
        !           885:                                result=not;
        !           886:                                (*ptrptr)++;
        !           887:                                break;
        !           888:                        case AR_SUBCODE:
        !           889:                                result=not;
        !           890:                                while(*(*ptrptr))
        !           891:                                        (*ptrptr)++;
        !           892:                                break;
        !           893:                        case AR_LIB:
        !           894:                                result=not;
        !           895:                                (*ptrptr)++;
        !           896:                                break;
        !           897:                        case AR_DIR:
        !           898:                                result=not;
        !           899:                                (*ptrptr)++;
        !           900:                                break;
        !           901:                        case AR_DIRCODE:
        !           902:                                result=not;
        !           903:                                while(*(*ptrptr))
        !           904:                                        (*ptrptr)++;
        !           905:                                break;
        !           906:                        case AR_EXPIRE:
        !           907:                                now=time(NULL);
        !           908:                                if(!user->expire || now+((long)i*24L*60L*60L)>user->expire)
        !           909:                                        result=not;
        !           910:                                else
        !           911:                                        result=!not;
        !           912:                                (*ptrptr)++;
        !           913:                                break;
        !           914:                        case AR_RANDOM:
        !           915:                                n=sbbs_random(i+1);
        !           916:                                if((equal && n!=i) || (!equal && n<i))
        !           917:                                        result=not;
        !           918:                                else
        !           919:                                        result=!not;
        !           920:                                (*ptrptr)++;
        !           921:                                break;
        !           922:                        case AR_LASTON:
        !           923:                                now=time(NULL);
        !           924:                                if((now-user->laston)/(24L*60L*60L)<(long)i)
        !           925:                                        result=not;
        !           926:                                else
        !           927:                                        result=!not;
        !           928:                                (*ptrptr)++;
        !           929:                                break;
        !           930:                        case AR_LOGONS:
        !           931:                                if((equal && user->logons!=i) || (!equal && user->logons<i))
        !           932:                                        result=not;
        !           933:                                else
        !           934:                                        result=!not;
        !           935:                                (*ptrptr)++;
        !           936:                                break;
        !           937:                        case AR_MAIN_CMDS:
        !           938:                                result=not;
        !           939:                                (*ptrptr)++;
        !           940:                                break;
        !           941:                        case AR_FILE_CMDS:
        !           942:                                result=not;
        !           943:                                (*ptrptr)++;
        !           944:                                break;
        !           945:                        case AR_TLEFT:
        !           946:                                result=not;
        !           947:                                break;
        !           948:                        case AR_TUSED:
        !           949:                                result=not;
        !           950:                                break;
        !           951:                        case AR_TIME:
        !           952:                                now=time(NULL);
        !           953:                                tm=gmtime(&now);
        !           954:                                if(tm==NULL || (tm->tm_hour*60)+tm->tm_min<(int)i)
        !           955:                                        result=not;
        !           956:                                else
        !           957:                                        result=!not;
        !           958:                                (*ptrptr)++;
        !           959:                                break;
        !           960:                        case AR_PCR:
        !           961:                                if(user->logons>user->posts
        !           962:                                        && (!user->posts || 100/(user->logons/user->posts)<(long)n))
        !           963:                                        result=not;
        !           964:                                else
        !           965:                                        result=!not;
        !           966:                                break;
        !           967:                        case AR_UDR:    /* up/download byte ratio */
        !           968:                                l=user->dlb;
        !           969:                                if(!l) l=1;
        !           970:                                if(user->dlb>user->ulb
        !           971:                                        && (!user->ulb || 100/(l/user->ulb)<n))
        !           972:                                        result=not;
        !           973:                                else
        !           974:                                        result=!not;
        !           975:                                break;
        !           976:                        case AR_UDFR:   /* up/download file ratio */
        !           977:                                i=user->dls;
        !           978:                                if(!i) i=1;
        !           979:                                if(user->dls>user->uls
        !           980:                                        && (!user->uls || 100/(i/user->uls)<n))
        !           981:                                        result=not;
        !           982:                                else
        !           983:                                        result=!not;
        !           984:                                break;
        !           985:                        case AR_FLAG1:
        !           986:                                if((!equal && !(user->flags1&FLAG(n)))
        !           987:                                        || (equal && user->flags1!=FLAG(n)))
        !           988:                                        result=not;
        !           989:                                else
        !           990:                                        result=!not;
        !           991:                                break;
        !           992:                        case AR_FLAG2:
        !           993:                                if((!equal && !(user->flags2&FLAG(n)))
        !           994:                                        || (equal && user->flags2!=FLAG(n)))
        !           995:                                        result=not;
        !           996:                                else
        !           997:                                        result=!not;
        !           998:                                break;
        !           999:                        case AR_FLAG3:
        !          1000:                                if((!equal && !(user->flags3&FLAG(n)))
        !          1001:                                        || (equal && user->flags3!=FLAG(n)))
        !          1002:                                        result=not;
        !          1003:                                else
        !          1004:                                        result=!not;
        !          1005:                                break;
        !          1006:                        case AR_FLAG4:
        !          1007:                                if((!equal && !(user->flags4&FLAG(n)))
        !          1008:                                        || (equal && user->flags4!=FLAG(n)))
        !          1009:                                        result=not;
        !          1010:                                else
        !          1011:                                        result=!not;
        !          1012:                                break;
        !          1013:                        case AR_REST:
        !          1014:                                if((!equal && !(user->rest&FLAG(n)))
        !          1015:                                        || (equal && user->rest!=FLAG(n)))
        !          1016:                                        result=not;
        !          1017:                                else
        !          1018:                                        result=!not;
        !          1019:                                break;
        !          1020:                        case AR_EXEMPT:
        !          1021:                                if((!equal && !(user->exempt&FLAG(n)))
        !          1022:                                        || (equal && user->exempt!=FLAG(n)))
        !          1023:                                        result=not;
        !          1024:                                else
        !          1025:                                        result=!not;
        !          1026:                                break;
        !          1027:                        case AR_SEX:
        !          1028:                                if(user->sex!=n)
        !          1029:                                        result=not;
        !          1030:                                else
        !          1031:                                        result=!not;
        !          1032:                                break; } }
        !          1033:        return(result);
        !          1034: }
        !          1035: 
        !          1036: BOOL DLLCALL chk_ar(scfg_t* cfg, uchar *ar, user_t* user)
        !          1037: {
        !          1038:        uchar *p;
        !          1039: 
        !          1040:        if(ar==NULL)
        !          1041:                return(TRUE);
        !          1042:        p=ar;
        !          1043:        return(ar_exp(cfg,&p,user));
        !          1044: }
        !          1045: 
        !          1046: /****************************************************************************/
        !          1047: /* Fills 'str' with record for usernumber starting at start for length bytes*/
        !          1048: /* Called from function ???                                                                                                    */
        !          1049: /****************************************************************************/
        !          1050: int DLLCALL getuserrec(scfg_t* cfg, int usernumber,int start, int length, char *str)
        !          1051: {
        !          1052:        char c,path[256];
        !          1053:        int i,file;
        !          1054: 
        !          1055:        if(!usernumber)
        !          1056:                return(-1);
        !          1057:        sprintf(path,"%suser/user.dat",cfg->data_dir);
        !          1058:        if((file=nopen(path,O_RDONLY|O_DENYNONE))==-1) 
        !          1059:                return(errno);
        !          1060:        if(usernumber<1
        !          1061:                || filelength(file)<(long)((long)(usernumber-1L)*U_LEN)+(long)start) {
        !          1062:                close(file);
        !          1063:                return(-2); 
        !          1064:        }
        !          1065:        lseek(file,(long)((long)(usernumber-1)*U_LEN)+start,SEEK_SET);
        !          1066: 
        !          1067:        i=0;
        !          1068:        while(i<LOOP_NODEDAB
        !          1069:                && lock(file,(long)((long)(usernumber-1)*U_LEN)+start,length)==-1) {
        !          1070:                if(i>10)
        !          1071:                        mswait(55);
        !          1072:                i++; }
        !          1073: 
        !          1074:        if(i>=LOOP_NODEDAB) {
        !          1075:                close(file);
        !          1076:                return(-3); 
        !          1077:        }
        !          1078: 
        !          1079:        if(read(file,str,length)!=length) {
        !          1080:                unlock(file,(long)((long)(usernumber-1)*U_LEN)+start,length);
        !          1081:                close(file);
        !          1082:                return(-4); 
        !          1083:        }
        !          1084: 
        !          1085:        unlock(file,(long)((long)(usernumber-1)*U_LEN)+start,length);
        !          1086:        close(file);
        !          1087:        for(c=0;c<length;c++)
        !          1088:                if(str[c]==ETX || str[c]==CR) break;
        !          1089:        str[c]=0;
        !          1090: 
        !          1091:        return(0);
        !          1092: }
        !          1093: 
        !          1094: /****************************************************************************/
        !          1095: /* Places into user.dat at the offset for usernumber+start for length bytes */
        !          1096: /* Called from various locations                                                                                       */
        !          1097: /****************************************************************************/
        !          1098: int DLLCALL putuserrec(scfg_t* cfg, int usernumber,int start, uint length, char *str)
        !          1099: {
        !          1100:        char    str2[256];
        !          1101:        int             file;
        !          1102:        uint    c,i;
        !          1103:        node_t  node;
        !          1104: 
        !          1105:        if(usernumber<1)
        !          1106:                return(-1);
        !          1107: 
        !          1108:        sprintf(str2,"%suser/user.dat",cfg->data_dir);
        !          1109:        if((file=nopen(str2,O_WRONLY|O_DENYNONE))==-1)
        !          1110:                return(errno);
        !          1111: 
        !          1112:        strcpy(str2,str);
        !          1113:        if(strlen(str2)<length) {
        !          1114:                for(c=strlen(str2);c<length;c++)
        !          1115:                        str2[c]=ETX;
        !          1116:                str2[c]=0; 
        !          1117:        }
        !          1118:        lseek(file,(long)((long)((long)((long)usernumber-1)*U_LEN)+start),SEEK_SET);
        !          1119: 
        !          1120:        i=0;
        !          1121:        while(i<LOOP_NODEDAB
        !          1122:                && lock(file,(long)((long)(usernumber-1)*U_LEN)+start,length)==-1) {
        !          1123:                if(i>10)
        !          1124:                        mswait(55);
        !          1125:                i++; }
        !          1126: 
        !          1127:        if(i>=LOOP_NODEDAB) 
        !          1128:                return(-3);
        !          1129: 
        !          1130:        write(file,str2,length);
        !          1131:        unlock(file,(long)((long)(usernumber-1)*U_LEN)+start,length);
        !          1132:        close(file);
        !          1133:        for(i=1;i<=cfg->sys_nodes;i++) {        /* instant user data update */
        !          1134:                if(i==cfg->node_num)
        !          1135:                        continue;
        !          1136:                getnodedat(cfg, i,&node,0);
        !          1137:                if(node.useron==usernumber && (node.status==NODE_INUSE
        !          1138:                        || node.status==NODE_QUIET)) {
        !          1139:                        getnodedat(cfg, i,&node,1);
        !          1140:                        node.misc|=NODE_UDAT;
        !          1141:                        putnodedat(cfg, i,&node);
        !          1142:                        break; 
        !          1143:                } 
        !          1144:        }
        !          1145: 
        !          1146:        return(0);
        !          1147: }
        !          1148: 
        !          1149: /****************************************************************************/
        !          1150: /* Updates user 'usernumber's record (numeric string) by adding 'adj' to it */
        !          1151: /* returns the new value.                                                                                                      */
        !          1152: /****************************************************************************/
        !          1153: ulong DLLCALL adjustuserrec(scfg_t* cfg, int usernumber, int start, int length, long adj)
        !          1154: {
        !          1155:        char str[256],c,path[256];
        !          1156:        char tmp[32];
        !          1157:        int i,file;
        !          1158:        long val;
        !          1159:        node_t node;
        !          1160: 
        !          1161:        if(usernumber<1) 
        !          1162:                return(0UL); 
        !          1163: 
        !          1164:        sprintf(path,"%suser/user.dat",cfg->data_dir);
        !          1165:        if((file=nopen(path,O_RDWR|O_DENYNONE))==-1)
        !          1166:                return(0UL); 
        !          1167: 
        !          1168:        lseek(file,(long)((long)(usernumber-1)*U_LEN)+start,SEEK_SET);
        !          1169: 
        !          1170:        i=0;
        !          1171:        while(i<LOOP_NODEDAB
        !          1172:                && lock(file,(long)((long)(usernumber-1)*U_LEN)+start,length)==-1) {
        !          1173:                if(i>10)
        !          1174:                        mswait(55);
        !          1175:                i++; }
        !          1176: 
        !          1177:        if(i>=LOOP_NODEDAB) {
        !          1178:                close(file);
        !          1179:                return(0)        !          1180:        }
        !          1181: 
        !          1182:        if(read(file,str,length)!=length) {
        !          1183:                unlock(file,(long)((long)(usernumber-1)*U_LEN)+start,length);
        !          1184:                close(file);
        !          1185:                return(0UL); 
        !          1186:        }
        !          1187:        for(c=0;c<length;c++)
        !          1188:                if(str[c]==ETX || str[c]==CR) break;
        !          1189:        str[c]=0;
        !          1190:        val=atol(str);
        !          1191:        if(adj<0L && val<-adj)          /* don't go negative */
        !          1192:                val=0UL;
        !          1193:        else val+=adj;
        !          1194:        lseek(file,(long)((long)(usernumber-1)*U_LEN)+start,SEEK_SET);
        !          1195:        putrec(str,0,length,ultoa(val,tmp,10));
        !          1196:        if(write(file,str,length)!=length) {
        !          1197:                unlock(file,(long)((long)(usernumber-1)*U_LEN)+start,length);
        !          1198:                close(file);
        !          1199:                return(val); 
        !          1200:        }
        !          1201:        unlock(file,(long)((long)(usernumber-1)*U_LEN)+start,length);
        !          1202:        close(file);
        !          1203:        for(i=1;i<=cfg->sys_nodes;i++) { /* instant user data update */
        !          1204:                if(i==cfg->node_num)
        !          1205:                        continue;
        !          1206:                getnodedat(cfg, i,&node,0);
        !          1207:                if(node.useron==usernumber && (node.status==NODE_INUSE
        !          1208:                        || node.status==NODE_QUIET)) {
        !          1209:                        getnodedat(cfg, i,&node,1);
        !          1210:                        node.misc|=NODE_UDAT;
        !          1211:                        putnodedat(cfg, i,&node);
        !          1212:                        break; 
        !          1213:                } 
        !          1214:        }
        !          1215:        return(val);
        !          1216: }
        !          1217: 
        !          1218: /****************************************************************************/
        !          1219: /* Subtract credits from the current user online, accounting for the new    */
        !          1220: /* "free credits" field.                                                    */
        !          1221: /****************************************************************************/
        !          1222: void DLLCALL subtract_cdt(scfg_t* cfg, user_t* user, long amt)
        !          1223: {
        !          1224:        char tmp[64];
        !          1225:     long mod;
        !          1226: 
        !          1227:        if(!amt)
        !          1228:                return;
        !          1229:        if(user->freecdt) {
        !          1230:                if((ulong)amt>user->freecdt) {      /* subtract both credits and */
        !          1231:                        mod=amt-user->freecdt;   /* free credits */
        !          1232:                        putuserrec(cfg, user->number,U_FREECDT,10,"0");
        !          1233:                        user->freecdt=0;
        !          1234:                        user->cdt=adjustuserrec(cfg, user->number,U_CDT,10,-mod); }
        !          1235:                else {                          /* subtract just free credits */
        !          1236:                        user->freecdt-=amt;
        !          1237:                        putuserrec(cfg, user->number,U_FREECDT,10
        !          1238:                                ,ultoa(user->freecdt,tmp,10)); } }
        !          1239:        else    /* no free credits */
        !          1240:                user->cdt=adjustuserrec(cfg, user->number,U_CDT,10,-amt);
        !          1241: }

unix.superglobalmegacorp.com

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