|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.