|
|
1.1 ! root 1: /* userdat.c */ ! 2: ! 3: /* Synchronet user data-related routines (exported) */ ! 4: ! 5: /* $Id: userdat.c,v 1.101 2006/12/29 09:00:59 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 2006 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: #ifndef USHRT_MAX ! 41: #define USHRT_MAX ((unsigned short)~0) ! 42: #endif ! 43: ! 44: /* convenient space-saving global variables */ ! 45: char* crlf="\r\n"; ! 46: char* nulstr=""; ! 47: ! 48: #define VALID_CFG(cfg) (cfg!=NULL && cfg->size==sizeof(scfg_t)) ! 49: ! 50: /****************************************************************************/ ! 51: /* Looks for a perfect match amoung all usernames (not deleted users) */ ! 52: /* Makes dots and underscores synomynous with spaces for comparisions */ ! 53: /* Returns the number of the perfect matched username or 0 if no match */ ! 54: /****************************************************************************/ ! 55: uint DLLCALL matchuser(scfg_t* cfg, char *name, BOOL sysop_alias) ! 56: { ! 57: int file,c; ! 58: char* p; ! 59: char dat[LEN_ALIAS+2]; ! 60: char str[256]; ! 61: ulong l,length; ! 62: FILE* stream; ! 63: ! 64: if(!VALID_CFG(cfg) || name==NULL) ! 65: return(0); ! 66: ! 67: if(sysop_alias && ! 68: (!stricmp(name,"SYSOP") || !stricmp(name,"POSTMASTER") || !stricmp(name,cfg->sys_id))) ! 69: return(1); ! 70: ! 71: sprintf(str,"%suser/name.dat",cfg->data_dir); ! 72: if((file=nopen(str,O_RDONLY))==-1) ! 73: return(0); ! 74: length=filelength(file); ! 75: if((stream=fdopen(file,"rb"))==NULL) ! 76: return(0); ! 77: for(l=0;l<length;l+=LEN_ALIAS+2) { ! 78: fread(dat,sizeof(dat),1,stream); ! 79: for(c=0;c<LEN_ALIAS;c++) ! 80: if(dat[c]==ETX) break; ! 81: dat[c]=0; ! 82: if(!stricmp(dat,name)) ! 83: break; ! 84: /* convert dots to spaces */ ! 85: strcpy(str,dat); ! 86: REPLACE_CHARS(str,'.',' ',p); ! 87: if(!stricmp(str,name)) ! 88: break; ! 89: /* convert spaces to dots */ ! 90: strcpy(str,dat); ! 91: REPLACE_CHARS(str,' ','.',p); ! 92: if(!stricmp(str,name)) ! 93: break; ! 94: /* convert dots to underscores */ ! 95: strcpy(str,dat); ! 96: REPLACE_CHARS(str,'.','_',p); ! 97: if(!stricmp(str,name)) ! 98: break; ! 99: /* convert underscores to dots */ ! 100: strcpy(str,dat); ! 101: REPLACE_CHARS(str,'_','.',p); ! 102: if(!stricmp(str,name)) ! 103: break; ! 104: /* convert spaces to underscores */ ! 105: strcpy(str,dat); ! 106: REPLACE_CHARS(str,' ','_',p); ! 107: if(!stricmp(str,name)) ! 108: break; ! 109: /* convert underscores to spaces */ ! 110: strcpy(str,dat); ! 111: REPLACE_CHARS(str,'_',' ',p); ! 112: if(!stricmp(str,name)) ! 113: break; ! 114: } ! 115: fclose(stream); ! 116: if(l<length) ! 117: return((l/(LEN_ALIAS+2))+1); ! 118: return(0); ! 119: } ! 120: ! 121: /****************************************************************************/ ! 122: uint DLLCALL total_users(scfg_t* cfg) ! 123: { ! 124: char str[MAX_PATH+1]; ! 125: uint total_users=0; ! 126: int file; ! 127: long l,length; ! 128: ! 129: if(!VALID_CFG(cfg)) ! 130: return(0); ! 131: ! 132: sprintf(str,"%suser/user.dat", cfg->data_dir); ! 133: if((file=nopen(str,O_RDONLY|O_DENYNONE))==-1) ! 134: return(0); ! 135: length=filelength(file); ! 136: for(l=0;l<length;l+=U_LEN) { ! 137: lseek(file,l+U_MISC,SEEK_SET); ! 138: if(read(file,str,8)!=8) ! 139: continue; ! 140: getrec(str,0,8,str); ! 141: if(ahtoul(str)&(DELETED|INACTIVE)) ! 142: continue; ! 143: total_users++; ! 144: } ! 145: close(file); ! 146: return(total_users); ! 147: } ! 148: ! 149: ! 150: /****************************************************************************/ ! 151: /* Returns the number of the last user in user.dat (deleted ones too) */ ! 152: /****************************************************************************/ ! 153: uint DLLCALL lastuser(scfg_t* cfg) ! 154: { ! 155: char str[256]; ! 156: long length; ! 157: ! 158: if(!VALID_CFG(cfg)) ! 159: return(0); ! 160: ! 161: sprintf(str,"%suser/user.dat", cfg->data_dir); ! 162: if((length=flength(str))>0) ! 163: return((uint)(length/U_LEN)); ! 164: return(0); ! 165: } ! 166: ! 167: /****************************************************************************/ ! 168: /* Deletes last user record in user.dat */ ! 169: /****************************************************************************/ ! 170: BOOL DLLCALL del_lastuser(scfg_t* cfg) ! 171: { ! 172: char str[256]; ! 173: int file; ! 174: long length; ! 175: ! 176: if(!VALID_CFG(cfg)) ! 177: return(FALSE); ! 178: ! 179: sprintf(str,"%suser/user.dat", cfg->data_dir); ! 180: if((file=nopen(str,O_RDWR|O_DENYNONE))==-1) ! 181: return(FALSE); ! 182: length=filelength(file); ! 183: if(length<U_LEN) { ! 184: close(file); ! 185: return(FALSE); ! 186: } ! 187: chsize(file,length-U_LEN); ! 188: close(file); ! 189: return(TRUE); ! 190: } ! 191: ! 192: ! 193: /****************************************************************************/ ! 194: /* Fills the structure 'user' with info for user.number from user.dat */ ! 195: /* Called from functions useredit, waitforcall and main_sec */ ! 196: /****************************************************************************/ ! 197: int DLLCALL getuserdat(scfg_t* cfg, user_t *user) ! 198: { ! 199: char userdat[U_LEN+1],str[U_LEN+1],tmp[64]; ! 200: int i,file; ! 201: unsigned user_number; ! 202: ! 203: if(user==NULL) ! 204: return(-1); ! 205: ! 206: user_number=user->number; ! 207: memset(user,0,sizeof(user_t)); ! 208: ! 209: if(!VALID_CFG(cfg) || user_number<1) ! 210: return(-1); ! 211: ! 212: sprintf(userdat,"%suser/user.dat",cfg->data_dir); ! 213: if((file=nopen(userdat,O_RDONLY|O_DENYNONE))==-1) ! 214: return(errno); ! 215: ! 216: if(user_number > (unsigned)(filelength(file)/U_LEN)) { ! 217: close(file); ! 218: return(-1); /* no such user record */ ! 219: } ! 220: lseek(file,(long)((long)(user_number-1)*U_LEN),SEEK_SET); ! 221: i=0; ! 222: while(i<LOOP_NODEDAB ! 223: && lock(file,(long)((long)(user_number-1)*U_LEN),U_LEN)==-1) { ! 224: if(i) ! 225: mswait(100); ! 226: i++; ! 227: } ! 228: ! 229: if(i>=LOOP_NODEDAB) { ! 230: close(file); ! 231: return(-2); ! 232: } ! 233: ! 234: if(read(file,userdat,U_LEN)!=U_LEN) { ! 235: unlock(file,(long)((long)(user_number-1)*U_LEN),U_LEN); ! 236: close(file); ! 237: return(-3); ! 238: } ! 239: ! 240: unlock(file,(long)((long)(user_number-1)*U_LEN),U_LEN); ! 241: close(file); ! 242: /* order of these function calls is irrelevant */ ! 243: getrec(userdat,U_ALIAS,LEN_ALIAS,user->alias); ! 244: getrec(userdat,U_NAME,LEN_NAME,user->name); ! 245: getrec(userdat,U_HANDLE,LEN_HANDLE,user->handle); ! 246: getrec(userdat,U_NOTE,LEN_NOTE,user->note); ! 247: getrec(userdat,U_COMP,LEN_COMP,user->comp); ! 248: getrec(userdat,U_COMMENT,LEN_COMMENT,user->comment); ! 249: getrec(userdat,U_NETMAIL,LEN_NETMAIL,user->netmail); ! 250: getrec(userdat,U_ADDRESS,LEN_ADDRESS,user->address); ! 251: getrec(userdat,U_LOCATION,LEN_LOCATION,user->location); ! 252: getrec(userdat,U_ZIPCODE,LEN_ZIPCODE,user->zipcode); ! 253: getrec(userdat,U_PASS,LEN_PASS,user->pass); ! 254: getrec(userdat,U_PHONE,LEN_PHONE,user->phone); ! 255: getrec(userdat,U_BIRTH,LEN_BIRTH,user->birth); ! 256: getrec(userdat,U_MODEM,LEN_MODEM,user->modem); ! 257: getrec(userdat,U_LASTON,8,str); user->laston=ahtoul(str); ! 258: getrec(userdat,U_FIRSTON,8,str); user->firston=ahtoul(str); ! 259: getrec(userdat,U_EXPIRE,8,str); user->expire=ahtoul(str); ! 260: getrec(userdat,U_PWMOD,8,str); user->pwmod=ahtoul(str); ! 261: getrec(userdat,U_NS_TIME,8,str); ! 262: user->ns_time=ahtoul(str); ! 263: if(user->ns_time<0x20000000L) ! 264: user->ns_time=user->laston; /* Fix for v2.00->v2.10 */ ! 265: getrec(userdat,U_LOGONTIME,8,str); user->logontime=ahtoul(str); ! 266: ! 267: getrec(userdat,U_LOGONS,5,str); user->logons=atoi(str); ! 268: getrec(userdat,U_LTODAY,5,str); user->ltoday=atoi(str); ! 269: getrec(userdat,U_TIMEON,5,str); user->timeon=atoi(str); ! 270: getrec(userdat,U_TEXTRA,5,str); user->textra=atoi(str); ! 271: getrec(userdat,U_TTODAY,5,str); user->ttoday=atoi(str); ! 272: getrec(userdat,U_TLAST,5,str); user->tlast=atoi(str); ! 273: getrec(userdat,U_POSTS,5,str); user->posts=atoi(str); ! 274: getrec(userdat,U_EMAILS,5,str); user->emails=atoi(str); ! 275: getrec(userdat,U_FBACKS,5,str); user->fbacks=atoi(str); ! 276: getrec(userdat,U_ETODAY,5,str); user->etoday=atoi(str); ! 277: getrec(userdat,U_PTODAY,5,str); user->ptoday=atoi(str); ! 278: getrec(userdat,U_ULB,10,str); user->ulb=atol(str); ! 279: getrec(userdat,U_ULS,5,str); user->uls=atoi(str); ! 280: getrec(userdat,U_DLB,10,str); user->dlb=atol(str); ! 281: getrec(userdat,U_DLS,5,str); user->dls=atoi(str); ! 282: getrec(userdat,U_CDT,10,str); user->cdt=atol(str); ! 283: getrec(userdat,U_MIN,10,str); user->min=atol(str); ! 284: getrec(userdat,U_LEVEL,2,str); user->level=atoi(str); ! 285: getrec(userdat,U_FLAGS1,8,str); user->flags1=ahtoul(str); ! 286: getrec(userdat,U_FLAGS2,8,str); user->flags2=ahtoul(str); ! 287: getrec(userdat,U_FLAGS3,8,str); user->flags3=ahtoul(str); ! 288: getrec(userdat,U_FLAGS4,8,str); user->flags4=ahtoul(str); ! 289: getrec(userdat,U_EXEMPT,8,str); user->exempt=ahtoul(str); ! 290: getrec(userdat,U_REST,8,str); user->rest=ahtoul(str); ! 291: getrec(userdat,U_ROWS,2,str); user->rows=atoi(str); ! 292: if(user->rows && user->rows<10) ! 293: user->rows=10; ! 294: user->sex=userdat[U_SEX]; ! 295: if(!user->sex) ! 296: user->sex=' '; /* fix for v1b04 that could save as 0 */ ! 297: user->prot=userdat[U_PROT]; ! 298: if(user->prot<' ') ! 299: user->prot=' '; ! 300: getrec(userdat,U_MISC,8,str); user->misc=ahtoul(str); ! 301: if(user->rest&FLAG('Q')) ! 302: user->misc&=~SPIN; ! 303: ! 304: getrec(userdat,U_LEECH,2,str); ! 305: user->leech=(uchar)ahtoul(str); ! 306: getrec(userdat,U_CURSUB,sizeof(user->cursub)-1,user->cursub); ! 307: getrec(userdat,U_CURDIR,sizeof(user->curdir)-1,user->curdir); ! 308: getrec(userdat,U_CURXTRN,8,user->curxtrn); ! 309: ! 310: getrec(userdat,U_FREECDT,10,str); ! 311: user->freecdt=atol(str); ! 312: ! 313: getrec(userdat,U_XEDIT,8,str); ! 314: for(i=0;i<cfg->total_xedits;i++) ! 315: if(!stricmp(str,cfg->xedit[i]->code) && chk_ar(cfg,cfg->xedit[i]->ar,user)) ! 316: break; ! 317: user->xedit=i+1; ! 318: if(user->xedit>cfg->total_xedits) ! 319: user->xedit=0; ! 320: ! 321: getrec(userdat,U_SHELL,8,str); ! 322: for(i=0;i<cfg->total_shells;i++) ! 323: if(!stricmp(str,cfg->shell[i]->code)) ! 324: break; ! 325: if(i==cfg->total_shells) ! 326: i=0; ! 327: user->shell=i; ! 328: ! 329: getrec(userdat,U_QWK,8,str); ! 330: if(str[0]<' ') { /* v1c, so set defaults */ ! 331: if(user->rest&FLAG('Q')) ! 332: user->qwk=QWK_DEFAULT|QWK_RETCTLA; ! 333: else ! 334: user->qwk=QWK_DEFAULT; ! 335: } ! 336: else ! 337: user->qwk=ahtoul(str); ! 338: ! 339: getrec(userdat,U_TMPEXT,3,user->tmpext); ! 340: if((!user->tmpext[0] || !strcmp(user->tmpext,"0")) && cfg->total_fcomps) ! 341: strcpy(user->tmpext,cfg->fcomp[0]->ext); /* For v1x to v2x conversion */ ! 342: ! 343: getrec(userdat,U_CHAT,8,str); ! 344: user->chat=ahtoul(str); ! 345: ! 346: /* Reset daily stats if not logged on today */ ! 347: unixtodstr(cfg, time(NULL),str); ! 348: unixtodstr(cfg, user->laston,tmp); ! 349: if(strcmp(str,tmp) && user->ltoday) ! 350: resetdailyuserdat(cfg,user); ! 351: ! 352: #if 0 /* removed 01/19/00 Why? ToDo */ ! 353: if(useron.number==user_number) { ! 354: if(user!=&useron) ! 355: useron=*user; ! 356: ! 357: if(online) { ! 358: ! 359: #if 0 /* legacy? ToDo */ ! 360: getusrdirs(); ! 361: getusrsubs(); ! 362: #endif ! 363: if(user->misc&AUTOTERM) { /* was useron.misc (01/19/00) */ ! 364: user->misc&=~(ANSI|RIP|WIP|HTML); ! 365: user->misc|=autoterm; ! 366: } ! 367: } ! 368: } ! 369: #endif ! 370: user->number=user_number; /* Signal of success */ ! 371: ! 372: return(0); ! 373: } ! 374: ! 375: /****************************************************************************/ ! 376: /* Writes into user.number's slot in user.dat data in structure 'user' */ ! 377: /* Called from functions newuser, useredit and main */ ! 378: /****************************************************************************/ ! 379: int DLLCALL putuserdat(scfg_t* cfg, user_t* user) ! 380: { ! 381: int i,file; ! 382: char userdat[U_LEN],str[MAX_PATH+1]; ! 383: node_t node; ! 384: ! 385: if(user==NULL) ! 386: return(-1); ! 387: ! 388: if(!VALID_CFG(cfg) || user->number<1) ! 389: return(-1); ! 390: ! 391: memset(userdat,ETX,U_LEN); ! 392: putrec(userdat,U_ALIAS,LEN_ALIAS+5,user->alias); ! 393: putrec(userdat,U_NAME,LEN_NAME,user->name); ! 394: putrec(userdat,U_HANDLE,LEN_HANDLE,user->handle); ! 395: putrec(userdat,U_HANDLE+LEN_HANDLE,2,crlf); ! 396: ! 397: putrec(userdat,U_NOTE,LEN_NOTE,user->note); ! 398: putrec(userdat,U_COMP,LEN_COMP,user->comp); ! 399: putrec(userdat,U_COMP+LEN_COMP,2,crlf); ! 400: ! 401: putrec(userdat,U_COMMENT,LEN_COMMENT,user->comment); ! 402: putrec(userdat,U_COMMENT+LEN_COMMENT,2,crlf); ! 403: ! 404: putrec(userdat,U_NETMAIL,LEN_NETMAIL,user->netmail); ! 405: putrec(userdat,U_NETMAIL+LEN_NETMAIL,2,crlf); ! 406: ! 407: putrec(userdat,U_ADDRESS,LEN_ADDRESS,user->address); ! 408: putrec(userdat,U_LOCATION,LEN_LOCATION,user->location); ! 409: putrec(userdat,U_ZIPCODE,LEN_ZIPCODE,user->zipcode); ! 410: putrec(userdat,U_ZIPCODE+LEN_ZIPCODE,2,crlf); ! 411: ! 412: putrec(userdat,U_PASS,LEN_PASS,user->pass); ! 413: putrec(userdat,U_PHONE,LEN_PHONE,user->phone); ! 414: putrec(userdat,U_BIRTH,LEN_BIRTH,user->birth); ! 415: putrec(userdat,U_MODEM,LEN_MODEM,user->modem); ! 416: putrec(userdat,U_LASTON,8,ultoa(user->laston,str,16)); ! 417: putrec(userdat,U_FIRSTON,8,ultoa(user->firston,str,16)); ! 418: putrec(userdat,U_EXPIRE,8,ultoa(user->expire,str,16)); ! 419: putrec(userdat,U_PWMOD,8,ultoa(user->pwmod,str,16)); ! 420: putrec(userdat,U_PWMOD+8,2,crlf); ! 421: ! 422: putrec(userdat,U_LOGONS,5,ultoa(user->logons,str,10)); ! 423: putrec(userdat,U_LTODAY,5,ultoa(user->ltoday,str,10)); ! 424: putrec(userdat,U_TIMEON,5,ultoa(user->timeon,str,10)); ! 425: putrec(userdat,U_TEXTRA,5,ultoa(user->textra,str,10)); ! 426: putrec(userdat,U_TTODAY,5,ultoa(user->ttoday,str,10)); ! 427: putrec(userdat,U_TLAST,5,ultoa(user->tlast,str,10)); ! 428: putrec(userdat,U_POSTS,5,ultoa(user->posts,str,10)); ! 429: putrec(userdat,U_EMAILS,5,ultoa(user->emails,str,10)); ! 430: putrec(userdat,U_FBACKS,5,ultoa(user->fbacks,str,10)); ! 431: putrec(userdat,U_ETODAY,5,ultoa(user->etoday,str,10)); ! 432: putrec(userdat,U_PTODAY,5,ultoa(user->ptoday,str,10)); ! 433: putrec(userdat,U_PTODAY+5,2,crlf); ! 434: ! 435: putrec(userdat,U_ULB,10,ultoa(user->ulb,str,10)); ! 436: putrec(userdat,U_ULS,5,ultoa(user->uls,str,10)); ! 437: putrec(userdat,U_DLB,10,ultoa(user->dlb,str,10)); ! 438: putrec(userdat,U_DLS,5,ultoa(user->dls,str,10)); ! 439: putrec(userdat,U_CDT,10,ultoa(user->cdt,str,10)); ! 440: putrec(userdat,U_MIN,10,ultoa(user->min,str,10)); ! 441: putrec(userdat,U_MIN+10,2,crlf); ! 442: ! 443: putrec(userdat,U_LEVEL,2,ultoa(user->level,str,10)); ! 444: putrec(userdat,U_FLAGS1,8,ultoa(user->flags1,str,16)); ! 445: putrec(userdat,U_TL,2,nulstr); /* unused */ ! 446: putrec(userdat,U_FLAGS2,8,ultoa(user->flags2,str,16)); ! 447: putrec(userdat,U_EXEMPT,8,ultoa(user->exempt,str,16)); ! 448: putrec(userdat,U_REST,8,ultoa(user->rest,str,16)); ! 449: putrec(userdat,U_REST+8,2,crlf); ! 450: ! 451: putrec(userdat,U_ROWS,2,ultoa(user->rows,str,10)); ! 452: userdat[U_SEX]=user->sex; ! 453: userdat[U_PROT]=user->prot; ! 454: putrec(userdat,U_MISC,8,ultoa(user->misc,str,16)); ! 455: putrec(userdat,U_LEECH,2,ultoa(user->leech,str,16)); ! 456: ! 457: putrec(userdat,U_CURSUB,sizeof(user->cursub)-1,user->cursub); ! 458: putrec(userdat,U_CURDIR,sizeof(user->curdir)-1,user->curdir); ! 459: putrec(userdat,U_CURXTRN,8,user->curxtrn); ! 460: putrec(userdat,U_CURXTRN+8,2,crlf); ! 461: ! 462: putrec(userdat,U_XFER_CMD+LEN_XFER_CMD,2,crlf); ! 463: ! 464: putrec(userdat,U_MAIL_CMD+LEN_MAIL_CMD,2,crlf); ! 465: ! 466: putrec(userdat,U_FREECDT,10,ultoa(user->freecdt,str,10)); ! 467: ! 468: putrec(userdat,U_FLAGS3,8,ultoa(user->flags3,str,16)); ! 469: putrec(userdat,U_FLAGS4,8,ultoa(user->flags4,str,16)); ! 470: ! 471: if(user->xedit) ! 472: putrec(userdat,U_XEDIT,8,cfg->xedit[user->xedit-1]->code); ! 473: else ! 474: putrec(userdat,U_XEDIT,8,nulstr); ! 475: ! 476: putrec(userdat,U_SHELL,8,cfg->shell[user->shell]->code); ! 477: ! 478: putrec(userdat,U_QWK,8,ultoa(user->qwk,str,16)); ! 479: putrec(userdat,U_TMPEXT,3,user->tmpext); ! 480: putrec(userdat,U_CHAT,8,ultoa(user->chat,str,16)); ! 481: putrec(userdat,U_NS_TIME,8,ultoa(user->ns_time,str,16)); ! 482: putrec(userdat,U_LOGONTIME,8,ultoa(user->logontime,str,16)); ! 483: ! 484: putrec(userdat,U_UNUSED,U_LEN-(U_UNUSED)-2,crlf); ! 485: putrec(userdat,U_UNUSED+(U_LEN-(U_UNUSED)-2),2,crlf); ! 486: ! 487: sprintf(str,"%suser/user.dat", cfg->data_dir); ! 488: if((file=nopen(str,O_RDWR|O_CREAT|O_DENYNONE))==-1) { ! 489: return(errno); ! 490: } ! 491: ! 492: if(filelength(file)<((long)user->number-1)*U_LEN) { ! 493: close(file); ! 494: return(-4); ! 495: } ! 496: ! 497: lseek(file,(long)((long)((long)user->number-1)*U_LEN),SEEK_SET); ! 498: ! 499: i=0; ! 500: while(i<LOOP_NODEDAB ! 501: && lock(file,(long)((long)(user->number-1)*U_LEN),U_LEN)==-1) { ! 502: if(i) ! 503: mswait(100); ! 504: i++; ! 505: } ! 506: ! 507: if(i>=LOOP_NODEDAB) { ! 508: close(file); ! 509: return(-2); ! 510: } ! 511: ! 512: if(write(file,userdat,U_LEN)!=U_LEN) { ! 513: unlock(file,(long)((long)(user->number-1)*U_LEN),U_LEN); ! 514: close(file); ! 515: return(-3); ! 516: } ! 517: unlock(file,(long)((long)(user->number-1)*U_LEN),U_LEN); ! 518: close(file); ! 519: for(i=1;i<=cfg->sys_nodes;i++) { /* instant user data update */ ! 520: if(i==cfg->node_num) ! 521: continue; ! 522: getnodedat(cfg, i,&node,NULL); ! 523: if(node.useron==user->number && (node.status==NODE_INUSE ! 524: || node.status==NODE_QUIET)) { ! 525: getnodedat(cfg, i,&node,&file); ! 526: node.misc|=NODE_UDAT; ! 527: putnodedat(cfg, i,&node,file); ! 528: break; ! 529: } ! 530: } ! 531: return(0); ! 532: } ! 533: ! 534: ! 535: /****************************************************************************/ ! 536: /* Returns the username in 'str' that corresponds to the 'usernumber' */ ! 537: /* Called from functions everywhere */ ! 538: /****************************************************************************/ ! 539: char* DLLCALL username(scfg_t* cfg, int usernumber, char *name) ! 540: { ! 541: char str[256]; ! 542: int c; ! 543: int file; ! 544: ! 545: if(name==NULL) ! 546: return(NULL); ! 547: ! 548: if(!VALID_CFG(cfg) || usernumber<1) { ! 549: name[0]=0; ! 550: return(name); ! 551: } ! 552: sprintf(str,"%suser/name.dat",cfg->data_dir); ! 553: if(flength(str)<1L) { ! 554: name[0]=0; ! 555: return(name); ! 556: } ! 557: if((file=nopen(str,O_RDONLY))==-1) { ! 558: name[0]=0; ! 559: return(name); ! 560: } ! 561: if(filelength(file)<(long)((long)usernumber*(LEN_ALIAS+2))) { ! 562: close(file); ! 563: name[0]=0; ! 564: return(name); ! 565: } ! 566: lseek(file,(long)((long)(usernumber-1)*(LEN_ALIAS+2)),SEEK_SET); ! 567: read(file,name,LEN_ALIAS); ! 568: close(file); ! 569: for(c=0;c<LEN_ALIAS;c++) ! 570: if(name[c]==ETX) break; ! 571: name[c]=0; ! 572: if(!c) ! 573: strcpy(name,"DELETED USER"); ! 574: return(name); ! 575: } ! 576: ! 577: /****************************************************************************/ ! 578: /* Puts 'name' into slot 'number' in user/name.dat */ ! 579: /****************************************************************************/ ! 580: int DLLCALL putusername(scfg_t* cfg, int number, char *name) ! 581: { ! 582: char str[256]; ! 583: int file; ! 584: int wr; ! 585: long length; ! 586: uint total_users; ! 587: ! 588: if(!VALID_CFG(cfg) || name==NULL || number<1) ! 589: return(-1); ! 590: ! 591: sprintf(str,"%suser/name.dat", cfg->data_dir); ! 592: if((file=nopen(str,O_RDWR|O_CREAT))==-1) ! 593: return(errno); ! 594: length=filelength(file); ! 595: ! 596: /* Truncate corrupted name.dat */ ! 597: total_users=lastuser(cfg); ! 598: if((uint)(length/(LEN_ALIAS+2))>total_users) ! 599: chsize(file,total_users*(LEN_ALIAS+2)); ! 600: ! 601: if(length && length%(LEN_ALIAS+2)) { ! 602: close(file); ! 603: return(-3); ! 604: } ! 605: if(length<(((long)number-1)*(LEN_ALIAS+2))) { ! 606: sprintf(str,"%*s",LEN_ALIAS,nulstr); ! 607: memset(str,ETX,LEN_ALIAS); ! 608: strcat(str,crlf); ! 609: lseek(file,0L,SEEK_END); ! 610: while(filelength(file)<((long)number*(LEN_ALIAS+2))) ! 611: write(file,str,(LEN_ALIAS+2)); ! 612: } ! 613: lseek(file,(long)(((long)number-1)*(LEN_ALIAS+2)),SEEK_SET); ! 614: putrec(str,0,LEN_ALIAS,name); ! 615: putrec(str,LEN_ALIAS,2,crlf); ! 616: wr=write(file,str,LEN_ALIAS+2); ! 617: close(file); ! 618: ! 619: if(wr!=LEN_ALIAS+2) ! 620: return(errno); ! 621: return(0); ! 622: } ! 623: ! 624: /****************************************************************************/ ! 625: /* Returns the age derived from the string 'birth' in the format MM/DD/YY */ ! 626: /****************************************************************************/ ! 627: char DLLCALL getage(scfg_t* cfg, char *birth) ! 628: { ! 629: char age; ! 630: struct tm tm; ! 631: time_t now; ! 632: ! 633: if(!VALID_CFG(cfg) || birth==NULL) ! 634: return(0); ! 635: ! 636: if(!atoi(birth) || !atoi(birth+3)) /* Invalid */ ! 637: return(0); ! 638: ! 639: now=time(NULL); ! 640: if(localtime_r(&now,&tm)==NULL) ! 641: return(0); ! 642: age=(tm.tm_year)-(((birth[6]&0xf)*10)+(birth[7]&0xf)); ! 643: if(age>105) ! 644: age-=105; ! 645: tm.tm_mon++; /* convert to 1 based */ ! 646: if(cfg->sys_misc&SM_EURODATE) { /* DD/MM/YY format */ ! 647: if(atoi(birth)>31 || atoi(birth+3)>12) ! 648: return(0); ! 649: if(((birth[3]&0xf)*10)+(birth[4]&0xf)>tm.tm_mon || ! 650: (((birth[3]&0xf)*10)+(birth[4]&0xf)==tm.tm_mon && ! 651: ((birth[0]&0xf)*10)+(birth[1]&0xf)>tm.tm_mday)) ! 652: age--; ! 653: } else { /* MM/DD/YY format */ ! 654: if(atoi(birth)>12 || atoi(birth+3)>31) ! 655: return(0); ! 656: if(((birth[0]&0xf)*10)+(birth[1]&0xf)>tm.tm_mon || ! 657: (((birth[0]&0xf)*10)+(birth[1]&0xf)==tm.tm_mon && ! 658: ((birth[3]&0xf)*10)+(birth[4]&0xf)>tm.tm_mday)) ! 659: age--; ! 660: } ! 661: if(age<0) ! 662: return(0); ! 663: return(age); ! 664: } ! 665: ! 666: ! 667: /****************************************************************************/ ! 668: /* Reads the data for node number 'number' into the structure 'node' */ ! 669: /* from node.dab */ ! 670: /****************************************************************************/ ! 671: int DLLCALL getnodedat(scfg_t* cfg, uint number, node_t *node, int* fdp) ! 672: { ! 673: char str[MAX_PATH+1]; ! 674: int rd; ! 675: int count=0; ! 676: int file; ! 677: ! 678: if(fdp!=NULL) ! 679: *fdp=-1; ! 680: ! 681: if(!VALID_CFG(cfg) ! 682: || node==NULL || number<1 || number>cfg->sys_nodes) ! 683: return(-1); ! 684: ! 685: memset(node,0,sizeof(node_t)); ! 686: sprintf(str,"%snode.dab",cfg->ctrl_dir); ! 687: if((file=nopen(str,O_RDWR|O_DENYNONE))==-1) ! 688: return(errno); ! 689: ! 690: if(filelength(file)>=(long)(number*sizeof(node_t))) { ! 691: number--; /* make zero based */ ! 692: for(count=0;count<LOOP_NODEDAB;count++) { ! 693: if(count) ! 694: mswait(100); ! 695: lseek(file,(long)number*sizeof(node_t),SEEK_SET); ! 696: if(fdp!=NULL ! 697: && lock(file,(long)number*sizeof(node_t),sizeof(node_t))!=0) ! 698: continue; ! 699: rd=read(file,node,sizeof(node_t)); ! 700: if(fdp==NULL || rd!=sizeof(node_t)) ! 701: unlock(file,(long)number*sizeof(node_t),sizeof(node_t)); ! 702: if(rd==sizeof(node_t)) ! 703: break; ! 704: } ! 705: } ! 706: ! 707: if(fdp==NULL || count==LOOP_NODEDAB) ! 708: close(file); ! 709: else ! 710: *fdp=file; ! 711: ! 712: if(count==LOOP_NODEDAB) ! 713: return(-2); ! 714: ! 715: return(0); ! 716: } ! 717: ! 718: /****************************************************************************/ ! 719: /* Write the data from the structure 'node' into node.dab */ ! 720: /****************************************************************************/ ! 721: int DLLCALL putnodedat(scfg_t* cfg, uint number, node_t* node, int file) ! 722: { ! 723: size_t wr=0; ! 724: int wrerr=0; ! 725: int attempts; ! 726: ! 727: if(!VALID_CFG(cfg) ! 728: || node==NULL || number<1 || number>cfg->sys_nodes || file<0) { ! 729: close(file); ! 730: return(-1); ! 731: } ! 732: ! 733: number--; /* make zero based */ ! 734: for(attempts=0;attempts<10;attempts++) { ! 735: lseek(file,(long)number*sizeof(node_t),SEEK_SET); ! 736: if((wr=write(file,node,sizeof(node_t)))==sizeof(node_t)) ! 737: break; ! 738: wrerr=errno; /* save write error */ ! 739: mswait(100); ! 740: } ! 741: unlock(file,(long)number*sizeof(node_t),sizeof(node_t)); ! 742: close(file); ! 743: ! 744: if(wr!=sizeof(node_t)) ! 745: return(wrerr); ! 746: return(0); ! 747: } ! 748: ! 749: /****************************************************************************/ ! 750: /* Packs the password 'pass' into 5bit ASCII inside node_t. 32bits in */ ! 751: /* node.extaux, and the other 8bits in the upper byte of node.aux */ ! 752: /****************************************************************************/ ! 753: void DLLCALL packchatpass(char *pass, node_t *node) ! 754: { ! 755: char bits; ! 756: int i,j; ! 757: ! 758: if(pass==NULL || node==NULL) ! 759: return; ! 760: ! 761: node->aux&=~0xff00; /* clear the password */ ! 762: node->extaux=0L; ! 763: if((j=strlen(pass))==0) /* there isn't a password */ ! 764: return; ! 765: node->aux|=(int)((pass[0]-64)<<8); /* 1st char goes in low 5bits of aux */ ! 766: if(j==1) /* password is only one char, we're done */ ! 767: return; ! 768: node->aux|=(int)((pass[1]-64)<<13); /* low 3bits of 2nd char go in aux */ ! 769: node->extaux|=(long)((pass[1]-64)>>3); /* high 2bits of 2nd char go extaux */ ! 770: bits=2; ! 771: for(i=2;i<j;i++) { /* now process the 3rd char through the last */ ! 772: node->extaux|=(long)((long)(pass[i]-64)<<bits); ! 773: bits+=5; ! 774: } ! 775: } ! 776: ! 777: /****************************************************************************/ ! 778: /* Unpacks the password 'pass' from the 5bit ASCII inside node_t. 32bits in */ ! 779: /* node.extaux, and the other 8bits in the upper byte of node.aux */ ! 780: /****************************************************************************/ ! 781: char* DLLCALL unpackchatpass(char *pass, node_t* node) ! 782: { ! 783: char bits; ! 784: int i; ! 785: ! 786: if(pass==NULL || node==NULL) ! 787: return(NULL); ! 788: ! 789: pass[0]=(node->aux&0x1f00)>>8; ! 790: pass[1]=(char)(((node->aux&0xe000)>>13)|((node->extaux&0x3)<<3)); ! 791: bits=2; ! 792: for(i=2;i<8;i++) { ! 793: pass[i]=(char)((node->extaux>>bits)&0x1f); ! 794: bits+=5; ! 795: } ! 796: pass[8]=0; ! 797: for(i=0;i<8;i++) ! 798: if(pass[i]) ! 799: pass[i]+=64; ! 800: return(pass); ! 801: } ! 802: ! 803: char* DLLCALL nodestatus(scfg_t* cfg, node_t* node, char* buf, size_t buflen) ! 804: { ! 805: char str[256]; ! 806: char* mer; ! 807: int hour; ! 808: ! 809: if(node==NULL) { ! 810: strncpy(buf,"(null)",buflen); ! 811: return(buf); ! 812: } ! 813: ! 814: switch(node->status) { ! 815: case NODE_WFC: ! 816: strcpy(str,"Waiting for call"); ! 817: break; ! 818: case NODE_OFFLINE: ! 819: strcpy(str,"Offline"); ! 820: break; ! 821: case NODE_NETTING: ! 822: strcpy(str,"Networking"); ! 823: break; ! 824: case NODE_LOGON: ! 825: strcpy(str,"At logon prompt"); ! 826: break; ! 827: case NODE_EVENT_WAITING: ! 828: strcpy(str,"Waiting for all nodes to become inactive"); ! 829: break; ! 830: case NODE_EVENT_LIMBO: ! 831: sprintf(str,"Waiting for node %d to finish external event" ! 832: ,node->aux); ! 833: break; ! 834: case NODE_EVENT_RUNNING: ! 835: strcpy(str,"Running external event"); ! 836: break; ! 837: case NODE_NEWUSER: ! 838: strcpy(str,"New user applying for access "); ! 839: if(!node->connection) ! 840: strcat(str,"Locally"); ! 841: else if(node->connection==0xffff) { ! 842: strcat(str,"via telnet"); ! 843: } else ! 844: sprintf(str+strlen(str),"at %ubps",node->connection); ! 845: break; ! 846: case NODE_QUIET: ! 847: case NODE_INUSE: ! 848: username(cfg,node->useron,str); ! 849: strcat(str," "); ! 850: switch(node->action) { ! 851: case NODE_MAIN: ! 852: strcat(str,"at main menu"); ! 853: break; ! 854: case NODE_RMSG: ! 855: strcat(str,"reading messages"); ! 856: break; ! 857: case NODE_RMAL: ! 858: strcat(str,"reading mail"); ! 859: break; ! 860: case NODE_RSML: ! 861: strcat(str,"reading sent mail"); ! 862: break; ! 863: case NODE_RTXT: ! 864: strcat(str,"reading text files"); ! 865: break; ! 866: case NODE_PMSG: ! 867: strcat(str,"posting message"); ! 868: break; ! 869: case NODE_SMAL: ! 870: strcat(str,"sending mail"); ! 871: break; ! 872: case NODE_AMSG: ! 873: strcat(str,"posting auto-message"); ! 874: break; ! 875: case NODE_XTRN: ! 876: if(!node->aux) ! 877: strcat(str,"at external program menu"); ! 878: else if(node->aux<=cfg->total_xtrns) ! 879: sprintf(str+strlen(str),"running %s" ! 880: ,cfg->xtrn[node->aux-1]->name); ! 881: else ! 882: sprintf(str+strlen(str),"running external program #%d" ! 883: ,node->aux); ! 884: break; ! 885: case NODE_DFLT: ! 886: strcat(str,"changing defaults"); ! 887: break; ! 888: case NODE_XFER: ! 889: strcat(str,"at transfer menu"); ! 890: break; ! 891: case NODE_RFSD: ! 892: sprintf(str+strlen(str),"retrieving from device #%d",node->aux); ! 893: break; ! 894: case NODE_DLNG: ! 895: strcat(str,"downloading"); ! 896: break; ! 897: case NODE_ULNG: ! 898: strcat(str,"uploading"); ! 899: break; ! 900: case NODE_BXFR: ! 901: strcat(str,"transferring bidirectional"); ! 902: break; ! 903: case NODE_LFIL: ! 904: strcat(str,"listing files"); ! 905: break; ! 906: case NODE_LOGN: ! 907: strcat(str,"logging on"); ! 908: break; ! 909: case NODE_LCHT: ! 910: strcat(str,"in local chat with sysop"); ! 911: break; ! 912: case NODE_MCHT: ! 913: if(node->aux) { ! 914: sprintf(str+strlen(str),"in multinode chat channel %d" ! 915: ,node->aux&0xff); ! 916: if(node->aux&0x1f00) { /* password */ ! 917: strcat(str,"* "); ! 918: unpackchatpass(str+strlen(str),node); ! 919: } ! 920: } ! 921: else ! 922: strcat(str,"in multinode global chat channel"); ! 923: break; ! 924: case NODE_PAGE: ! 925: sprintf(str+strlen(str) ! 926: ,"paging node %u for private chat",node->aux); ! 927: break; ! 928: case NODE_PCHT: ! 929: if(!node->aux) ! 930: strcat(str,"in local chat with sysop"); ! 931: else ! 932: sprintf(str+strlen(str) ! 933: ,"in private chat with node %u" ! 934: ,node->aux); ! 935: break; ! 936: case NODE_GCHT: ! 937: strcat(str,"chatting with The Guru"); ! 938: break; ! 939: case NODE_CHAT: ! 940: strcat(str,"in chat section"); ! 941: break; ! 942: case NODE_TQWK: ! 943: strcat(str,"transferring QWK packet"); ! 944: break; ! 945: case NODE_SYSP: ! 946: strcat(str,"performing sysop activities"); ! 947: break; ! 948: default: ! 949: sprintf(str+strlen(str),"%d",node->action); ! 950: break; ! 951: } ! 952: if(!node->connection) ! 953: strcat(str," locally"); ! 954: if(node->connection==0xffff) { ! 955: strcat(str," via telnet"); ! 956: } else ! 957: sprintf(str+strlen(str)," at %ubps",node->connection); ! 958: if(node->action==NODE_DLNG) { ! 959: if((node->aux/60)>=12) { ! 960: if(node->aux/60==12) ! 961: hour=12; ! 962: else ! 963: hour=(node->aux/60)-12; ! 964: mer="pm"; ! 965: } else { ! 966: if((node->aux/60)==0) /* 12 midnite */ ! 967: hour=12; ! 968: else hour=node->aux/60; ! 969: mer="am"; ! 970: } ! 971: sprintf(str+strlen(str), " ETA %02d:%02d %s" ! 972: ,hour,node->aux-((node->aux/60)*60),mer); ! 973: } ! 974: break; ! 975: } ! 976: if(node->misc&(NODE_LOCK|NODE_POFF|NODE_AOFF|NODE_MSGW|NODE_NMSG)) { ! 977: strcat(str," ("); ! 978: if(node->misc&NODE_AOFF) ! 979: strcat(str,"A"); ! 980: if(node->misc&NODE_LOCK) ! 981: strcat(str,"L"); ! 982: if(node->misc&(NODE_MSGW|NODE_NMSG)) ! 983: strcat(str,"M"); ! 984: if(node->misc&NODE_POFF) ! 985: strcat(str,"P"); ! 986: strcat(str,")"); ! 987: } ! 988: if(((node->misc ! 989: &(NODE_ANON|NODE_UDAT|NODE_INTR|NODE_RRUN|NODE_EVENT|NODE_DOWN)) ! 990: || node->status==NODE_QUIET)) { ! 991: strcat(str," ["); ! 992: if(node->misc&NODE_ANON) ! 993: strcat(str,"A"); ! 994: if(node->misc&NODE_INTR) ! 995: strcat(str,"I"); ! 996: if(node->misc&NODE_RRUN) ! 997: strcat(str,"R"); ! 998: if(node->misc&NODE_UDAT) ! 999: strcat(str,"U"); ! 1000: if(node->status==NODE_QUIET) ! 1001: strcat(str,"Q"); ! 1002: if(node->misc&NODE_EVENT) ! 1003: strcat(str,"E"); ! 1004: if(node->misc&NODE_DOWN) ! 1005: strcat(str,"D"); ! 1006: if(node->misc&NODE_LCHAT) ! 1007: strcat(str,"C"); ! 1008: strcat(str,"]"); ! 1009: } ! 1010: if(node->errors) ! 1011: sprintf(str+strlen(str) ! 1012: ," %d error%c",node->errors, node->errors>1 ? 's' : '\0' ); ! 1013: ! 1014: strncpy(buf,str,buflen); ! 1015: ! 1016: return(buf); ! 1017: } ! 1018: ! 1019: /****************************************************************************/ ! 1020: /* Displays the information for node number 'number' contained in 'node' */ ! 1021: /****************************************************************************/ ! 1022: void DLLCALL printnodedat(scfg_t* cfg, uint number, node_t* node) ! 1023: { ! 1024: char status[128]; ! 1025: ! 1026: printf("Node %2d: %s\n",number,nodestatus(cfg,node,status,sizeof(status))); ! 1027: } ! 1028: ! 1029: /****************************************************************************/ ! 1030: uint DLLCALL userdatdupe(scfg_t* cfg, uint usernumber, uint offset, uint datlen ! 1031: ,char *dat, BOOL del) ! 1032: { ! 1033: char str[MAX_PATH+1]; ! 1034: uint i; ! 1035: int file; ! 1036: long l,length; ! 1037: ! 1038: if(!VALID_CFG(cfg) || dat==NULL) ! 1039: return(0); ! 1040: ! 1041: truncsp(dat); ! 1042: sprintf(str,"%suser/user.dat", cfg->data_dir); ! 1043: if((file=nopen(str,O_RDONLY|O_DENYNONE))==-1) ! 1044: return(0); ! 1045: length=filelength(file); ! 1046: for(l=0;l<length;l+=U_LEN) { ! 1047: if(usernumber && l/U_LEN==(long)usernumber-1) ! 1048: continue; ! 1049: lseek(file,l+offset,SEEK_SET); ! 1050: i=0; ! 1051: while(i<LOOP_NODEDAB && lock(file,l,U_LEN)==-1) { ! 1052: if(i) ! 1053: mswait(100); ! 1054: i++; ! 1055: } ! 1056: ! 1057: if(i>=LOOP_NODEDAB) { ! 1058: close(file); ! 1059: return(0); ! 1060: } ! 1061: ! 1062: read(file,str,datlen); ! 1063: for(i=0;i<datlen;i++) ! 1064: if(str[i]==ETX) break; ! 1065: str[i]=0; ! 1066: truncsp(str); ! 1067: if(!stricmp(str,dat)) { ! 1068: if(!del) { /* Don't include deleted users in search */ ! 1069: lseek(file,l+U_MISC,SEEK_SET); ! 1070: read(file,str,8); ! 1071: getrec(str,0,8,str); ! 1072: if(ahtoul(str)&(DELETED|INACTIVE)) { ! 1073: unlock(file,l,U_LEN); ! 1074: continue; ! 1075: } ! 1076: } ! 1077: unlock(file,l,U_LEN); ! 1078: close(file); ! 1079: return((l/U_LEN)+1); ! 1080: } else ! 1081: unlock(file,l,U_LEN); ! 1082: } ! 1083: close(file); ! 1084: return(0); ! 1085: } ! 1086: ! 1087: /****************************************************************************/ ! 1088: /* Creates a short message for 'usernumber' that contains 'strin' */ ! 1089: /****************************************************************************/ ! 1090: int DLLCALL putsmsg(scfg_t* cfg, int usernumber, char *strin) ! 1091: { ! 1092: char str[256]; ! 1093: int file,i; ! 1094: node_t node; ! 1095: ! 1096: if(!VALID_CFG(cfg) || usernumber<1 || strin==NULL) ! 1097: return(-1); ! 1098: ! 1099: if(*strin==0) ! 1100: return(0); ! 1101: ! 1102: sprintf(str,"%smsgs/%4.4u.msg",cfg->data_dir,usernumber); ! 1103: if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) { ! 1104: return(errno); ! 1105: } ! 1106: i=strlen(strin); ! 1107: if(write(file,strin,i)!=i) { ! 1108: close(file); ! 1109: return(errno); ! 1110: } ! 1111: close(file); ! 1112: for(i=1;i<=cfg->sys_nodes;i++) { /* flag node if user on that msg waiting */ ! 1113: getnodedat(cfg,i,&node,NULL); ! 1114: if(node.useron==usernumber ! 1115: && (node.status==NODE_INUSE || node.status==NODE_QUIET) ! 1116: && !(node.misc&NODE_MSGW)) { ! 1117: getnodedat(cfg,i,&node,&file); ! 1118: node.misc|=NODE_MSGW; ! 1119: putnodedat(cfg,i,&node,file); ! 1120: } ! 1121: } ! 1122: return(0); ! 1123: } ! 1124: ! 1125: /****************************************************************************/ ! 1126: /* Returns any short messages waiting for user number, buffer must be freed */ ! 1127: /****************************************************************************/ ! 1128: char* DLLCALL getsmsg(scfg_t* cfg, int usernumber) ! 1129: { ! 1130: char str[MAX_PATH+1], *buf; ! 1131: int i; ! 1132: int file; ! 1133: long length; ! 1134: node_t node; ! 1135: ! 1136: if(!VALID_CFG(cfg) || usernumber<1) ! 1137: return(NULL); ! 1138: ! 1139: sprintf(str,"%smsgs/%4.4u.msg",cfg->data_dir,usernumber); ! 1140: if(flength(str)<1L) ! 1141: return(NULL); ! 1142: if((file=nopen(str,O_RDWR))==-1) ! 1143: return(NULL); ! 1144: length=filelength(file); ! 1145: if((buf=(char *)malloc(length+1))==NULL) { ! 1146: close(file); ! 1147: return(NULL); ! 1148: } ! 1149: if(read(file,buf,length)!=length) { ! 1150: close(file); ! 1151: free(buf); ! 1152: return(NULL); ! 1153: } ! 1154: chsize(file,0L); ! 1155: close(file); ! 1156: buf[length]=0; ! 1157: ! 1158: for(i=1;i<=cfg->sys_nodes;i++) { /* clear msg waiting flag */ ! 1159: getnodedat(cfg,i,&node,NULL); ! 1160: if(node.useron==usernumber ! 1161: && (node.status==NODE_INUSE || node.status==NODE_QUIET) ! 1162: && node.misc&NODE_MSGW) { ! 1163: getnodedat(cfg,i,&node,&file); ! 1164: node.misc&=~NODE_MSGW; ! 1165: putnodedat(cfg,i,&node,file); ! 1166: } ! 1167: } ! 1168: ! 1169: return(buf); /* caller must free */ ! 1170: } ! 1171: ! 1172: char* DLLCALL getnmsg(scfg_t* cfg, int node_num) ! 1173: { ! 1174: char str[MAX_PATH+1]; ! 1175: char* buf; ! 1176: int file; ! 1177: long length; ! 1178: node_t node; ! 1179: ! 1180: if(!VALID_CFG(cfg) || node_num<1) ! 1181: return(NULL); ! 1182: ! 1183: getnodedat(cfg,node_num,&node,&file); ! 1184: node.misc&=~NODE_NMSG; /* clear the NMSG flag */ ! 1185: putnodedat(cfg,node_num,&node,file); ! 1186: ! 1187: sprintf(str,"%smsgs/n%3.3u.msg",cfg->data_dir,node_num); ! 1188: if(flength(str)<1L) ! 1189: return(NULL); ! 1190: if((file=nopen(str,O_RDWR))==-1) ! 1191: return(NULL); ! 1192: length=filelength(file); ! 1193: if(!length) { ! 1194: close(file); ! 1195: return(NULL); ! 1196: } ! 1197: if((buf=(char *)malloc(length+1))==NULL) { ! 1198: close(file); ! 1199: return(NULL); ! 1200: } ! 1201: if(read(file,buf,length)!=length) { ! 1202: close(file); ! 1203: free(buf); ! 1204: return(NULL); ! 1205: } ! 1206: chsize(file,0L); ! 1207: close(file); ! 1208: buf[length]=0; ! 1209: ! 1210: return(buf); /* caller must free */ ! 1211: } ! 1212: ! 1213: /****************************************************************************/ ! 1214: /* Creates a short message for node 'num' that contains 'strin' */ ! 1215: /****************************************************************************/ ! 1216: int DLLCALL putnmsg(scfg_t* cfg, int num, char *strin) ! 1217: { ! 1218: char str[256]; ! 1219: int file,i; ! 1220: node_t node; ! 1221: ! 1222: if(!VALID_CFG(cfg) || num<1 || strin==NULL) ! 1223: return(-1); ! 1224: ! 1225: if(*strin==0) ! 1226: return(0); ! 1227: ! 1228: sprintf(str,"%smsgs/n%3.3u.msg",cfg->data_dir,num); ! 1229: if((file=nopen(str,O_WRONLY|O_CREAT))==-1) ! 1230: return(errno); ! 1231: lseek(file,0L,SEEK_END); /* Instead of opening with O_APPEND */ ! 1232: i=strlen(strin); ! 1233: if(write(file,strin,i)!=i) { ! 1234: close(file); ! 1235: return(errno); ! 1236: } ! 1237: close(file); ! 1238: getnodedat(cfg,num,&node,NULL); ! 1239: if((node.status==NODE_INUSE || node.status==NODE_QUIET) ! 1240: && !(node.misc&NODE_NMSG)) { ! 1241: getnodedat(cfg,num,&node,&file); ! 1242: node.misc|=NODE_NMSG; ! 1243: putnodedat(cfg,num,&node,file); ! 1244: } ! 1245: ! 1246: return(0); ! 1247: } ! 1248: ! 1249: static int getdirnum(scfg_t* cfg, char* code) ! 1250: { ! 1251: size_t i; ! 1252: ! 1253: for(i=0;i<cfg->total_dirs;i++) ! 1254: if(stricmp(cfg->dir[i]->code,code)==0) ! 1255: return(i); ! 1256: return(-1); ! 1257: } ! 1258: ! 1259: static int getlibnum(scfg_t* cfg, char* code) ! 1260: { ! 1261: size_t i; ! 1262: ! 1263: for(i=0;i<cfg->total_dirs;i++) ! 1264: if(stricmp(cfg->dir[i]->code,code)==0) ! 1265: return(cfg->dir[i]->lib); ! 1266: return(-1); ! 1267: } ! 1268: ! 1269: static int getsubnum(scfg_t* cfg, char* code) ! 1270: { ! 1271: size_t i; ! 1272: ! 1273: for(i=0;i<cfg->total_subs;i++) ! 1274: if(stricmp(cfg->sub[i]->code,code)==0) ! 1275: return(i); ! 1276: return(-1); ! 1277: } ! 1278: ! 1279: static int getgrpnum(scfg_t* cfg, char* code) ! 1280: { ! 1281: size_t i; ! 1282: ! 1283: for(i=0;i<cfg->total_subs;i++) ! 1284: if(stricmp(cfg->sub[i]->code,code)==0) ! 1285: return(cfg->sub[i]->grp); ! 1286: return(-1); ! 1287: } ! 1288: ! 1289: static BOOL ar_exp(scfg_t* cfg, uchar **ptrptr, user_t* user) ! 1290: { ! 1291: BOOL result,not,or,equal; ! 1292: uint i,n,artype=AR_LEVEL,age; ! 1293: ulong l; ! 1294: time_t now; ! 1295: struct tm tm; ! 1296: ! 1297: result = TRUE; ! 1298: ! 1299: for(;(**ptrptr);(*ptrptr)++) { ! 1300: ! 1301: if((**ptrptr)==AR_ENDNEST) ! 1302: break; ! 1303: ! 1304: not=or=equal = FALSE; ! 1305: ! 1306: if((**ptrptr)==AR_OR) { ! 1307: or=1; ! 1308: (*ptrptr)++; ! 1309: } ! 1310: ! 1311: if((**ptrptr)==AR_NOT) { ! 1312: not=1; ! 1313: (*ptrptr)++; ! 1314: } ! 1315: ! 1316: if((**ptrptr)==AR_EQUAL) { ! 1317: equal=1; ! 1318: (*ptrptr)++; ! 1319: } ! 1320: ! 1321: if((result && or) || (!result && !or)) ! 1322: break; ! 1323: ! 1324: if((**ptrptr)==AR_BEGNEST) { ! 1325: (*ptrptr)++; ! 1326: if(ar_exp(cfg,ptrptr,user)) ! 1327: result=!not; ! 1328: else ! 1329: result=not; ! 1330: while((**ptrptr)!=AR_ENDNEST && (**ptrptr)) /* in case of early exit */ ! 1331: (*ptrptr)++; ! 1332: if(!(**ptrptr)) ! 1333: break; ! 1334: continue; ! 1335: } ! 1336: ! 1337: artype=(**ptrptr); ! 1338: switch(artype) { ! 1339: case AR_ANSI: /* No arguments */ ! 1340: case AR_RIP: ! 1341: case AR_WIP: ! 1342: case AR_LOCAL: ! 1343: case AR_EXPERT: ! 1344: case AR_SYSOP: ! 1345: case AR_GUEST: ! 1346: case AR_QNODE: ! 1347: case AR_QUIET: ! 1348: case AR_OS2: ! 1349: case AR_DOS: ! 1350: break; ! 1351: default: ! 1352: (*ptrptr)++; ! 1353: break; ! 1354: } ! 1355: ! 1356: n=(**ptrptr); ! 1357: i=(*(short *)*ptrptr); ! 1358: switch(artype) { ! 1359: case AR_LEVEL: ! 1360: if(user==NULL ! 1361: || (equal && user->level!=n) ! 1362: || (!equal && user->level<n)) ! 1363: result=not; ! 1364: else ! 1365: result=!not; ! 1366: break; ! 1367: case AR_AGE: ! 1368: if(user==NULL) ! 1369: result=not; ! 1370: else { ! 1371: age=getage(cfg,user->birth); ! 1372: if((equal && age!=n) || (!equal && age<n)) ! 1373: result=not; ! 1374: else ! 1375: result=!not; ! 1376: } ! 1377: break; ! 1378: case AR_BPS: ! 1379: result=!not; ! 1380: (*ptrptr)++; ! 1381: break; ! 1382: case AR_ANSI: ! 1383: if(user==NULL || !(user->misc&ANSI)) ! 1384: result=not; ! 1385: else result=!not; ! 1386: break; ! 1387: case AR_RIP: ! 1388: if(user==NULL || !(user->misc&RIP)) ! 1389: result=not; ! 1390: else result=!not; ! 1391: break; ! 1392: case AR_WIP: ! 1393: if(user==NULL || !(user->misc&WIP)) ! 1394: result=not; ! 1395: else result=!not; ! 1396: break; ! 1397: case AR_OS2: ! 1398: #ifndef __OS2__ ! 1399: result=not; ! 1400: #else ! 1401: result=!not; ! 1402: #endif ! 1403: break; ! 1404: case AR_DOS: ! 1405: result=not; ! 1406: break; ! 1407: case AR_WIN32: ! 1408: #ifndef _WIN32 ! 1409: result=not; ! 1410: #else ! 1411: result=!not; ! 1412: #endif ! 1413: break; ! 1414: case AR_UNIX: ! 1415: #ifndef __unix__ ! 1416: result=not; ! 1417: #else ! 1418: result=!not; ! 1419: #endif ! 1420: break; ! 1421: case AR_LINUX: ! 1422: #ifndef __linux__ ! 1423: result=not; ! 1424: #else ! 1425: result=!not; ! 1426: #endif ! 1427: break; ! 1428: case AR_ACTIVE: ! 1429: if(user==NULL || user->misc&(DELETED|INACTIVE)) ! 1430: result=not; ! 1431: else result=!not; ! 1432: break; ! 1433: case AR_INACTIVE: ! 1434: if(user==NULL || !(user->misc&INACTIVE)) ! 1435: result=not; ! 1436: else result=!not; ! 1437: break; ! 1438: case AR_DELETED: ! 1439: if(user==NULL || !(user->misc&DELETED)) ! 1440: result=not; ! 1441: else result=!not; ! 1442: break; ! 1443: case AR_EXPERT: ! 1444: if(user==NULL || !(user->misc&EXPERT)) ! 1445: result=not; ! 1446: else result=!not; ! 1447: break; ! 1448: case AR_SYSOP: ! 1449: if(user==NULL || user->level<SYSOP_LEVEL) ! 1450: result=not; ! 1451: else result=!not; ! 1452: break; ! 1453: case AR_GUEST: ! 1454: if(user==NULL || !(user->rest&FLAG('G'))) ! 1455: result=not; ! 1456: else result=!not; ! 1457: break; ! 1458: case AR_QNODE: ! 1459: if(user==NULL || !(user->rest&FLAG('Q'))) ! 1460: result=not; ! 1461: else result=!not; ! 1462: break; ! 1463: case AR_QUIET: ! 1464: result=not; ! 1465: break; ! 1466: case AR_LOCAL: ! 1467: result=not; ! 1468: break; ! 1469: case AR_DAY: ! 1470: now=time(NULL); ! 1471: localtime_r(&now,&tm); ! 1472: if((equal && tm.tm_wday!=(int)n) ! 1473: || (!equal && tm.tm_wday<(int)n)) ! 1474: result=not; ! 1475: else ! 1476: result=!not; ! 1477: break; ! 1478: case AR_CREDIT: ! 1479: l=(ulong)i*1024UL; ! 1480: if(user==NULL ! 1481: || (equal && user->cdt+user->freecdt!=l) ! 1482: || (!equal && user->cdt+user->freecdt<l)) ! 1483: result=not; ! 1484: else ! 1485: result=!not; ! 1486: (*ptrptr)++; ! 1487: break; ! 1488: case AR_NODE: ! 1489: if((equal && cfg->node_num!=n) || (!equal && cfg->node_num<n)) ! 1490: result=not; ! 1491: else ! 1492: result=!not; ! 1493: break; ! 1494: case AR_USER: ! 1495: if(user==NULL ! 1496: || (equal && user->number!=i) ! 1497: || (!equal && user->number<i)) ! 1498: result=not; ! 1499: else ! 1500: result=!not; ! 1501: (*ptrptr)++; ! 1502: break; ! 1503: case AR_GROUP: ! 1504: if(user==NULL) ! 1505: result=not; ! 1506: else { ! 1507: l=getgrpnum(cfg,user->cursub); ! 1508: if((equal && l!=i) || (!equal && l<i)) ! 1509: result=not; ! 1510: else ! 1511: result=!not; ! 1512: } ! 1513: (*ptrptr)++; ! 1514: break; ! 1515: case AR_SUB: ! 1516: if(user==NULL) ! 1517: result=not; ! 1518: else { ! 1519: l=getsubnum(cfg,user->cursub); ! 1520: if((equal && l!=i) || (!equal && l<i)) ! 1521: result=not; ! 1522: else ! 1523: result=!not; ! 1524: } ! 1525: (*ptrptr)++; ! 1526: break; ! 1527: case AR_SUBCODE: ! 1528: if(user!=NULL && stricmp(user->cursub,(char *)*ptrptr)==0) ! 1529: result=!not; ! 1530: else ! 1531: result=not; ! 1532: result=not; ! 1533: while(*(*ptrptr)) ! 1534: (*ptrptr)++; ! 1535: break; ! 1536: case AR_LIB: ! 1537: if(user==NULL) ! 1538: result=not; ! 1539: else { ! 1540: l=getlibnum(cfg,user->curdir); ! 1541: if((equal && l!=i) || (!equal && l<i)) ! 1542: result=not; ! 1543: else ! 1544: result=!not; ! 1545: } ! 1546: (*ptrptr)++; ! 1547: break; ! 1548: case AR_DIR: ! 1549: if(user==NULL) ! 1550: result=not; ! 1551: else { ! 1552: l=getdirnum(cfg,user->curdir); ! 1553: if((equal && l!=i) || (!equal && l<i)) ! 1554: result=not; ! 1555: else ! 1556: result=!not; ! 1557: } ! 1558: (*ptrptr)++; ! 1559: break; ! 1560: case AR_DIRCODE: ! 1561: if(user!=NULL && stricmp(user->curdir,(char *)*ptrptr)==0) ! 1562: result=!not; ! 1563: else ! 1564: result=not; ! 1565: while(*(*ptrptr)) ! 1566: (*ptrptr)++; ! 1567: break; ! 1568: case AR_EXPIRE: ! 1569: now=time(NULL); ! 1570: if(user==NULL ! 1571: || user->expire==0 ! 1572: || now+((long)i*24L*60L*60L)>user->expire) ! 1573: result=not; ! 1574: else ! 1575: result=!not; ! 1576: (*ptrptr)++; ! 1577: break; ! 1578: case AR_RANDOM: ! 1579: n=xp_random(i+1); ! 1580: if((equal && n!=i) || (!equal && n<i)) ! 1581: result=not; ! 1582: else ! 1583: result=!not; ! 1584: (*ptrptr)++; ! 1585: break; ! 1586: case AR_LASTON: ! 1587: now=time(NULL); ! 1588: if(user==NULL || (now-user->laston)/(24L*60L*60L)<(long)i) ! 1589: result=not; ! 1590: else ! 1591: result=!not; ! 1592: (*ptrptr)++; ! 1593: break; ! 1594: case AR_LOGONS: ! 1595: if(user==NULL ! 1596: || (equal && user->logons!=i) ! 1597: || (!equal && user->logons<i)) ! 1598: result=not; ! 1599: else ! 1600: result=!not; ! 1601: (*ptrptr)++; ! 1602: break; ! 1603: case AR_MAIN_CMDS: ! 1604: result=not; ! 1605: (*ptrptr)++; ! 1606: break; ! 1607: case AR_FILE_CMDS: ! 1608: result=not; ! 1609: (*ptrptr)++; ! 1610: break; ! 1611: case AR_TLEFT: ! 1612: result=not; ! 1613: break; ! 1614: case AR_TUSED: ! 1615: result=not; ! 1616: break; ! 1617: case AR_TIME: ! 1618: now=time(NULL); ! 1619: localtime_r(&now,&tm); ! 1620: if((tm.tm_hour*60)+tm.tm_min<(int)i) ! 1621: result=not; ! 1622: else ! 1623: result=!not; ! 1624: (*ptrptr)++; ! 1625: break; ! 1626: case AR_PCR: ! 1627: if(user==NULL) ! 1628: result=not; ! 1629: else if(user->logons>user->posts ! 1630: && (!user->posts || 100/((float)user->logons/user->posts)<(long)n)) ! 1631: result=not; ! 1632: else ! 1633: result=!not; ! 1634: break; ! 1635: case AR_UDR: /* up/download byte ratio */ ! 1636: if(user==NULL) ! 1637: result=not; ! 1638: else { ! 1639: l=user->dlb; ! 1640: if(!l) l=1; ! 1641: if(user->dlb>user->ulb ! 1642: && (!user->ulb || 100/((float)l/user->ulb)<n)) ! 1643: result=not; ! 1644: else ! 1645: result=!not; ! 1646: } ! 1647: break; ! 1648: case AR_UDFR: /* up/download file ratio */ ! 1649: if(user==NULL) ! 1650: result=not; ! 1651: else { ! 1652: i=user->dls; ! 1653: if(!i) i=1; ! 1654: if(user->dls>user->uls ! 1655: && (!user->uls || 100/((float)i/user->uls)<n)) ! 1656: result=not; ! 1657: else ! 1658: result=!not; ! 1659: } ! 1660: break; ! 1661: case AR_FLAG1: ! 1662: if(user==NULL ! 1663: || (!equal && !(user->flags1&FLAG(n))) ! 1664: || (equal && user->flags1!=FLAG(n))) ! 1665: result=not; ! 1666: else ! 1667: result=!not; ! 1668: break; ! 1669: case AR_FLAG2: ! 1670: if(user==NULL ! 1671: || (!equal && !(user->flags2&FLAG(n))) ! 1672: || (equal && user->flags2!=FLAG(n))) ! 1673: result=not; ! 1674: else ! 1675: result=!not; ! 1676: break; ! 1677: case AR_FLAG3: ! 1678: if(user==NULL ! 1679: || (!equal && !(user->flags3&FLAG(n))) ! 1680: || (equal && user->flags3!=FLAG(n))) ! 1681: result=not; ! 1682: else ! 1683: result=!not; ! 1684: break; ! 1685: case AR_FLAG4: ! 1686: if(user==NULL ! 1687: || (!equal && !(user->flags4&FLAG(n))) ! 1688: || (equal && user->flags4!=FLAG(n))) ! 1689: result=not; ! 1690: else ! 1691: result=!not; ! 1692: break; ! 1693: case AR_REST: ! 1694: if(user==NULL ! 1695: || (!equal && !(user->rest&FLAG(n))) ! 1696: || (equal && user->rest!=FLAG(n))) ! 1697: result=not; ! 1698: else ! 1699: result=!not; ! 1700: break; ! 1701: case AR_EXEMPT: ! 1702: if(user==NULL ! 1703: || (!equal && !(user->exempt&FLAG(n))) ! 1704: || (equal && user->exempt!=FLAG(n))) ! 1705: result=not; ! 1706: else ! 1707: result=!not; ! 1708: break; ! 1709: case AR_SEX: ! 1710: if(user==NULL || user->sex!=n) ! 1711: result=not; ! 1712: else ! 1713: result=!not; ! 1714: break; ! 1715: case AR_SHELL: ! 1716: if(user==NULL ! 1717: || user->shell>=cfg->total_shells ! 1718: || stricmp(cfg->shell[user->shell]->code,(char*)*ptrptr)) ! 1719: result=not; ! 1720: else ! 1721: result=!not; ! 1722: while(*(*ptrptr)) ! 1723: (*ptrptr)++; ! 1724: break; ! 1725: case AR_PROT: ! 1726: if(user==NULL ! 1727: || stricmp(user->modem,(char*)*ptrptr)) /* should this be changed to client.prot? */ ! 1728: result=not; ! 1729: else ! 1730: result=!not; ! 1731: while(*(*ptrptr)) ! 1732: (*ptrptr)++; ! 1733: break; ! 1734: } ! 1735: } ! 1736: return(result); ! 1737: } ! 1738: ! 1739: BOOL DLLCALL chk_ar(scfg_t* cfg, uchar *ar, user_t* user) ! 1740: { ! 1741: uchar *p; ! 1742: ! 1743: if(ar==NULL) ! 1744: return(TRUE); ! 1745: if(!VALID_CFG(cfg)) ! 1746: return(FALSE); ! 1747: p=ar; ! 1748: return(ar_exp(cfg,&p,user)); ! 1749: } ! 1750: ! 1751: /****************************************************************************/ ! 1752: /* Fills 'str' with record for usernumber starting at start for length bytes*/ ! 1753: /* Called from function ??? */ ! 1754: /****************************************************************************/ ! 1755: int DLLCALL getuserrec(scfg_t* cfg, int usernumber,int start, int length, char *str) ! 1756: { ! 1757: char path[256]; ! 1758: int i,c,file; ! 1759: ! 1760: if(!VALID_CFG(cfg) || usernumber<1 || str==NULL) ! 1761: return(-1); ! 1762: sprintf(path,"%suser/user.dat",cfg->data_dir); ! 1763: if((file=nopen(path,O_RDONLY|O_DENYNONE))==-1) ! 1764: return(errno); ! 1765: if(usernumber<1 ! 1766: || filelength(file)<(long)((long)(usernumber-1L)*U_LEN)+(long)start) { ! 1767: close(file); ! 1768: return(-2); ! 1769: } ! 1770: lseek(file,(long)((long)(usernumber-1)*U_LEN)+start,SEEK_SET); ! 1771: ! 1772: if(length==0) /* auto-length */ ! 1773: length=user_rec_len(start); ! 1774: ! 1775: i=0; ! 1776: while(i<LOOP_NODEDAB ! 1777: && lock(file,(long)((long)(usernumber-1)*U_LEN)+start,length)==-1) { ! 1778: if(i) ! 1779: mswait(100); ! 1780: i++; ! 1781: } ! 1782: ! 1783: if(i>=LOOP_NODEDAB) { ! 1784: close(file); ! 1785: return(-3); ! 1786: } ! 1787: ! 1788: if(read(file,str,length)!=length) { ! 1789: unlock(file,(long)((long)(usernumber-1)*U_LEN)+start,length); ! 1790: close(file); ! 1791: return(-4); ! 1792: } ! 1793: ! 1794: unlock(file,(long)((long)(usernumber-1)*U_LEN)+start,length); ! 1795: close(file); ! 1796: for(c=0;c<length;c++) ! 1797: if(str[c]==ETX || str[c]==CR) break; ! 1798: str[c]=0; ! 1799: ! 1800: return(0); ! 1801: } ! 1802: ! 1803: /****************************************************************************/ ! 1804: /* Places into user.dat at the offset for usernumber+start for length bytes */ ! 1805: /* Called from various locations */ ! 1806: /****************************************************************************/ ! 1807: int DLLCALL putuserrec(scfg_t* cfg, int usernumber,int start, uint length, char *str) ! 1808: { ! 1809: char str2[256]; ! 1810: int file; ! 1811: uint c,i; ! 1812: node_t node; ! 1813: ! 1814: if(!VALID_CFG(cfg) || usernumber<1 || str==NULL) ! 1815: return(-1); ! 1816: ! 1817: sprintf(str2,"%suser/user.dat",cfg->data_dir); ! 1818: if((file=nopen(str2,O_RDWR|O_DENYNONE))==-1) ! 1819: return(errno); ! 1820: ! 1821: if(filelength(file)<((long)usernumber-1)*U_LEN) { ! 1822: close(file); ! 1823: return(-4); ! 1824: } ! 1825: ! 1826: if(length==0) /* auto-length */ ! 1827: length=user_rec_len(start); ! 1828: ! 1829: strcpy(str2,str); ! 1830: if(strlen(str2)<length) { ! 1831: for(c=strlen(str2);c<length;c++) ! 1832: str2[c]=ETX; ! 1833: str2[c]=0; ! 1834: } ! 1835: lseek(file,(long)((long)((long)((long)usernumber-1)*U_LEN)+start),SEEK_SET); ! 1836: ! 1837: i=0; ! 1838: while(i<LOOP_NODEDAB ! 1839: && lock(file,(long)((long)(usernumber-1)*U_LEN)+start,length)==-1) { ! 1840: if(i) ! 1841: mswait(100); ! 1842: i++; ! 1843: } ! 1844: ! 1845: if(i>=LOOP_NODEDAB) ! 1846: return(-3); ! 1847: ! 1848: write(file,str2,length); ! 1849: unlock(file,(long)((long)(usernumber-1)*U_LEN)+start,length); ! 1850: close(file); ! 1851: for(i=1;i<=cfg->sys_nodes;i++) { /* instant user data update */ ! 1852: if(i==cfg->node_num) ! 1853: continue; ! 1854: getnodedat(cfg, i,&node,NULL); ! 1855: if(node.useron==usernumber && (node.status==NODE_INUSE ! 1856: || node.status==NODE_QUIET)) { ! 1857: getnodedat(cfg, i,&node,&file); ! 1858: node.misc|=NODE_UDAT; ! 1859: putnodedat(cfg, i,&node,file); ! 1860: break; ! 1861: } ! 1862: } ! 1863: ! 1864: return(0); ! 1865: } ! 1866: ! 1867: /****************************************************************************/ ! 1868: /* Updates user 'usernumber's record (numeric string) by adding 'adj' to it */ ! 1869: /* returns the new value. */ ! 1870: /****************************************************************************/ ! 1871: ulong DLLCALL adjustuserrec(scfg_t* cfg, int usernumber, int start, int length, long adj) ! 1872: { ! 1873: char str[256],path[256]; ! 1874: char tmp[32]; ! 1875: int i,c,file; ! 1876: long val; ! 1877: node_t node; ! 1878: ! 1879: if(!VALID_CFG(cfg) || usernumber<1) ! 1880: return(0); ! 1881: ! 1882: sprintf(path,"%suser/user.dat",cfg->data_dir); ! 1883: if((file=nopen(path,O_RDWR|O_DENYNONE))==-1) ! 1884: return(0); ! 1885: ! 1886: if(filelength(file)<((long)usernumber-1)*U_LEN) { ! 1887: close(file); ! 1888: return(0); ! 1889: } ! 1890: ! 1891: lseek(file,(long)((long)(usernumber-1)*U_LEN)+start,SEEK_SET); ! 1892: ! 1893: if(length==0) /* auto-length */ ! 1894: length=user_rec_len(start); ! 1895: ! 1896: i=0; ! 1897: while(i<LOOP_NODEDAB ! 1898: && lock(file,(long)((long)(usernumber-1)*U_LEN)+start,length)==-1) { ! 1899: if(i) ! 1900: mswait(100); ! 1901: i++; ! 1902: } ! 1903: ! 1904: if(i>=LOOP_NODEDAB) { ! 1905: close(file); ! 1906: return(0); ! 1907: } ! 1908: ! 1909: if(read(file,str,length)!=length) { ! 1910: unlock(file,(long)((long)(usernumber-1)*U_LEN)+start,length); ! 1911: close(file); ! 1912: return(0); ! 1913: } ! 1914: for(c=0;c<length;c++) ! 1915: if(str[c]==ETX || str[c]==CR) break; ! 1916: str[c]=0; ! 1917: val=atol(str); ! 1918: if(adj<0L && val<-adj) /* don't go negative */ ! 1919: val=0; ! 1920: else val+=adj; ! 1921: lseek(file,(long)((long)(usernumber-1)*U_LEN)+start,SEEK_SET); ! 1922: putrec(str,0,length,ultoa(val,tmp,10)); ! 1923: if(write(file,str,length)!=length) { ! 1924: unlock(file,(long)((long)(usernumber-1)*U_LEN)+start,length); ! 1925: close(file); ! 1926: return(val); ! 1927: } ! 1928: unlock(file,(long)((long)(usernumber-1)*U_LEN)+start,length); ! 1929: close(file); ! 1930: for(i=1;i<=cfg->sys_nodes;i++) { /* instant user data update */ ! 1931: if(i==cfg->node_num) ! 1932: continue; ! 1933: getnodedat(cfg, i,&node,NULL); ! 1934: if(node.useron==usernumber && (node.status==NODE_INUSE ! 1935: || node.status==NODE_QUIET)) { ! 1936: getnodedat(cfg, i,&node,&file); ! 1937: node.misc|=NODE_UDAT; ! 1938: putnodedat(cfg, i,&node,file); ! 1939: break; ! 1940: } ! 1941: } ! 1942: return(val); ! 1943: } ! 1944: ! 1945: /****************************************************************************/ ! 1946: /* Subtract credits from the current user online, accounting for the new */ ! 1947: /* "free credits" field. */ ! 1948: /****************************************************************************/ ! 1949: void DLLCALL subtract_cdt(scfg_t* cfg, user_t* user, long amt) ! 1950: { ! 1951: char tmp[64]; ! 1952: long mod; ! 1953: ! 1954: if(!amt || user==NULL) ! 1955: return; ! 1956: if(user->freecdt) { ! 1957: if((ulong)amt>user->freecdt) { /* subtract both credits and */ ! 1958: mod=amt-user->freecdt; /* free credits */ ! 1959: putuserrec(cfg, user->number,U_FREECDT,10,"0"); ! 1960: user->freecdt=0; ! 1961: user->cdt=adjustuserrec(cfg, user->number,U_CDT,10,-mod); ! 1962: } else { /* subtract just free credits */ ! 1963: user->freecdt-=amt; ! 1964: putuserrec(cfg, user->number,U_FREECDT,10 ! 1965: ,ultoa(user->freecdt,tmp,10)); ! 1966: } ! 1967: } ! 1968: else /* no free credits */ ! 1969: user->cdt=adjustuserrec(cfg, user->number,U_CDT,10,-amt); ! 1970: } ! 1971: ! 1972: BOOL DLLCALL user_posted_msg(scfg_t* cfg, user_t* user, int count) ! 1973: { ! 1974: if(user==NULL) ! 1975: return(FALSE); ! 1976: ! 1977: user->posts =(ushort)adjustuserrec(cfg, user->number, U_POSTS, 5, count); ! 1978: user->ptoday=(ushort)adjustuserrec(cfg, user->number, U_PTODAY, 5, count); ! 1979: ! 1980: return(TRUE); ! 1981: } ! 1982: ! 1983: BOOL DLLCALL user_sent_email(scfg_t* cfg, user_t* user, int count, BOOL feedback) ! 1984: { ! 1985: if(user==NULL) ! 1986: return(FALSE); ! 1987: ! 1988: if(feedback) ! 1989: user->fbacks=(ushort)adjustuserrec(cfg, user->number, U_FBACKS, 5, count); ! 1990: else ! 1991: user->emails=(ushort)adjustuserrec(cfg, user->number, U_EMAILS, 5, count); ! 1992: user->etoday=(ushort)adjustuserrec(cfg, user->number, U_ETODAY, 5, count); ! 1993: ! 1994: return(TRUE); ! 1995: } ! 1996: ! 1997: BOOL DLLCALL user_downloaded(scfg_t* cfg, user_t* user, int files, long bytes) ! 1998: { ! 1999: if(user==NULL) ! 2000: return(FALSE); ! 2001: ! 2002: user->dls=(ushort)adjustuserrec(cfg, user->number, U_DLS, 5, files); ! 2003: user->dlb=adjustuserrec(cfg, user->number, U_DLB, 10, bytes); ! 2004: ! 2005: return(TRUE); ! 2006: } ! 2007: ! 2008: BOOL DLLCALL user_uploaded(scfg_t* cfg, user_t* user, int files, long bytes) ! 2009: { ! 2010: if(user==NULL) ! 2011: return(FALSE); ! 2012: ! 2013: user->uls=(ushort)adjustuserrec(cfg, user->number, U_ULS, 5, files); ! 2014: user->ulb=adjustuserrec(cfg, user->number, U_ULB, 10, bytes); ! 2015: ! 2016: return(TRUE); ! 2017: } ! 2018: ! 2019: BOOL DLLCALL user_adjust_credits(scfg_t* cfg, user_t* user, long amount) ! 2020: { ! 2021: if(user==NULL) ! 2022: return(FALSE); ! 2023: ! 2024: if(amount<0) /* subtract */ ! 2025: subtract_cdt(cfg, user, -amount); ! 2026: else /* add */ ! 2027: user->cdt=adjustuserrec(cfg, user->number, U_CDT, 10, amount); ! 2028: ! 2029: return(TRUE); ! 2030: } ! 2031: ! 2032: BOOL DLLCALL user_adjust_minutes(scfg_t* cfg, user_t* user, long amount) ! 2033: { ! 2034: if(user==NULL) ! 2035: return(FALSE); ! 2036: ! 2037: user->min=adjustuserrec(cfg, user->number, U_MIN, 10, amount); ! 2038: ! 2039: return(TRUE); ! 2040: } ! 2041: ! 2042: /****************************************************************************/ ! 2043: /****************************************************************************/ ! 2044: BOOL DLLCALL logoutuserdat(scfg_t* cfg, user_t* user, time_t now, time_t logontime) ! 2045: { ! 2046: char str[128]; ! 2047: time_t tused; ! 2048: struct tm tm, tm_now; ! 2049: ! 2050: if(user==NULL) ! 2051: return(FALSE); ! 2052: ! 2053: if(now==0) ! 2054: now=time(NULL); ! 2055: ! 2056: tused=(now-logontime)/60; ! 2057: user->tlast=(ushort)(tused > USHRT_MAX ? USHRT_MAX : tused); ! 2058: ! 2059: putuserrec(cfg,user->number,U_LASTON,8,ultoa(now,str,16)); ! 2060: putuserrec(cfg,user->number,U_TLAST,5,ultoa(user->tlast,str,10)); ! 2061: adjustuserrec(cfg,user->number,U_TIMEON,5,user->tlast); ! 2062: adjustuserrec(cfg,user->number,U_TTODAY,5,user->tlast); ! 2063: ! 2064: /* Convert time_t to struct tm */ ! 2065: if(localtime_r(&now,&tm_now)==NULL) ! 2066: return(FALSE); ! 2067: ! 2068: if(localtime_r(&logontime,&tm)==NULL) ! 2069: return(FALSE); ! 2070: ! 2071: /* Reset daily stats if new day */ ! 2072: if(tm.tm_mday!=tm_now.tm_mday) ! 2073: resetdailyuserdat(cfg, user); ! 2074: ! 2075: return(TRUE); ! 2076: } ! 2077: ! 2078: /****************************************************************************/ ! 2079: /****************************************************************************/ ! 2080: void DLLCALL resetdailyuserdat(scfg_t* cfg, user_t* user) ! 2081: { ! 2082: char str[128]; ! 2083: ! 2084: if(!VALID_CFG(cfg) || user==NULL) ! 2085: return; ! 2086: ! 2087: /* logons today */ ! 2088: user->ltoday=0; ! 2089: putuserrec(cfg,user->number,U_LTODAY,5,"0"); ! 2090: /* e-mails today */ ! 2091: user->etoday=0; ! 2092: putuserrec(cfg,user->number,U_ETODAY,5,"0"); ! 2093: /* posts today */ ! 2094: user->ptoday=0; ! 2095: putuserrec(cfg,user->number,U_PTODAY,5,"0"); ! 2096: /* free credits per day */ ! 2097: user->freecdt=cfg->level_freecdtperday[user->level]; ! 2098: putuserrec(cfg,user->number,U_FREECDT,10 ! 2099: ,ultoa(user->freecdt,str,10)); ! 2100: /* time used today */ ! 2101: user->ttoday=0; ! 2102: putuserrec(cfg,user->number,U_TTODAY,5,"0"); ! 2103: /* extra time today */ ! 2104: user->textra=0; ! 2105: putuserrec(cfg,user->number,U_TEXTRA,5,"0"); ! 2106: } ! 2107: ! 2108: /****************************************************************************/ ! 2109: /****************************************************************************/ ! 2110: char* DLLCALL usermailaddr(scfg_t* cfg, char* addr, char* name) ! 2111: { ! 2112: int i; ! 2113: ! 2114: if(!VALID_CFG(cfg) || addr==NULL || name==NULL) ! 2115: return(NULL); ! 2116: ! 2117: if(strchr(name,'@')!=NULL) { /* Avoid double-@ */ ! 2118: strcpy(addr,name); ! 2119: return(addr); ! 2120: } ! 2121: if(strchr(name,'!') || (strchr(name,'.') && strchr(name,' '))) ! 2122: sprintf(addr,"\"%s\"@",name); ! 2123: else { ! 2124: sprintf(addr,"%s@",name); ! 2125: /* convert "first last@" to "first.last@" */ ! 2126: for(i=0;addr[i];i++) ! 2127: if(addr[i]==' ' || addr[i]&0x80) ! 2128: addr[i]='.'; ! 2129: strlwr(addr); ! 2130: } ! 2131: strcat(addr,cfg->sys_inetaddr); ! 2132: return(addr); ! 2133: } ! 2134: ! 2135: char* DLLCALL alias(scfg_t* cfg, char* name, char* buf) ! 2136: { ! 2137: char line[128]; ! 2138: char* p; ! 2139: char* np; ! 2140: char* tp; ! 2141: char* vp; ! 2142: char fname[MAX_PATH+1]; ! 2143: size_t namelen; ! 2144: size_t cmplen; ! 2145: FILE* fp; ! 2146: ! 2147: if(!VALID_CFG(cfg) || name==NULL || buf==NULL) ! 2148: return(NULL); ! 2149: ! 2150: p=name; ! 2151: ! 2152: sprintf(fname,"%salias.cfg",cfg->ctrl_dir); ! 2153: if((fp=fopen(fname,"r"))==NULL) ! 2154: return(name); ! 2155: ! 2156: while(!feof(fp)) { ! 2157: if(!fgets(line,sizeof(line),fp)) ! 2158: break; ! 2159: np=line; ! 2160: SKIP_WHITESPACE(np); ! 2161: if(*np==';' || *np==0) /* no name value, or comment */ ! 2162: continue; ! 2163: tp=np; ! 2164: FIND_WHITESPACE(tp); ! 2165: ! 2166: if(*tp==0) /* no alias value */ ! 2167: continue; ! 2168: *tp=0; ! 2169: ! 2170: vp=tp+1; ! 2171: SKIP_WHITESPACE(vp); ! 2172: truncsp(vp); ! 2173: if(*vp==0) /* no value */ ! 2174: continue; ! 2175: ! 2176: if(*np=='*') { ! 2177: np++; ! 2178: cmplen=strlen(np); ! 2179: namelen=strlen(name); ! 2180: if(namelen<cmplen) ! 2181: continue; ! 2182: if(strnicmp(np,name+(namelen-cmplen),cmplen)) ! 2183: continue; ! 2184: if(*vp=='*') ! 2185: sprintf(buf,"%.*s%s",(int)(namelen-cmplen),name,vp+1); ! 2186: else ! 2187: strcpy(buf,vp); ! 2188: p=buf; ! 2189: break; ! 2190: } ! 2191: if(!stricmp(np,name)) { ! 2192: strcpy(buf,vp); ! 2193: p=buf; ! 2194: break; ! 2195: } ! 2196: } ! 2197: fclose(fp); ! 2198: return(p); ! 2199: } ! 2200: ! 2201: int DLLCALL newuserdat(scfg_t* cfg, user_t* user) ! 2202: { ! 2203: char str[MAX_PATH+1]; ! 2204: char tmp[128]; ! 2205: int c; ! 2206: int i; ! 2207: int err; ! 2208: int file; ! 2209: int unum=1; ! 2210: int last; ! 2211: long misc; ! 2212: FILE* stream; ! 2213: stats_t stats; ! 2214: ! 2215: if(!VALID_CFG(cfg) || user==NULL) ! 2216: return(-1); ! 2217: ! 2218: sprintf(str,"%suser/name.dat",cfg->data_dir); ! 2219: if(fexist(str)) { ! 2220: if((stream=fnopen(&file,str,O_RDONLY))==NULL) { ! 2221: return(errno); ! 2222: } ! 2223: last=filelength(file)/(LEN_ALIAS+2); /* total users */ ! 2224: while(unum<=last) { ! 2225: fread(str,LEN_ALIAS+2,1,stream); ! 2226: for(c=0;c<LEN_ALIAS;c++) ! 2227: if(str[c]==ETX) break; ! 2228: str[c]=0; ! 2229: if(!c) { /* should be a deleted user */ ! 2230: getuserrec(cfg,unum,U_MISC,8,str); ! 2231: misc=ahtoul(str); ! 2232: if(misc&DELETED) { /* deleted bit set too */ ! 2233: getuserrec(cfg,unum,U_LASTON,8,str); ! 2234: if((time(NULL)-ahtoul(str))/86400>=cfg->sys_deldays) ! 2235: break; /* deleted long enough ? */ ! 2236: } ! 2237: } ! 2238: unum++; ! 2239: } ! 2240: fclose(stream); ! 2241: } ! 2242: ! 2243: last=lastuser(cfg); /* Check against data file */ ! 2244: ! 2245: if(unum>last+1) /* Corrupted name.dat? */ ! 2246: unum=last+1; ! 2247: else if(unum<=last) { /* Overwriting existing user */ ! 2248: getuserrec(cfg,unum,U_MISC,8,str); ! 2249: misc=ahtoul(str); ! 2250: if(!(misc&DELETED)) /* Not deleted? Set usernumber to end+1 */ ! 2251: unum=last+1; ! 2252: } ! 2253: ! 2254: user->number=unum; /* store the new user number */ ! 2255: ! 2256: if((err=putusername(cfg,user->number,user->alias))!=0) ! 2257: return(err); ! 2258: ! 2259: if((err=putuserdat(cfg,user))!=0) ! 2260: return(err); ! 2261: ! 2262: sprintf(str,"%sfile/%04u.in",cfg->data_dir,user->number); /* delete any files */ ! 2263: delfiles(str,ALLFILES); /* waiting for user */ ! 2264: rmdir(str); ! 2265: sprintf(tmp,"%04u.*",user->number); ! 2266: sprintf(str,"%sfile",cfg->data_dir); ! 2267: delfiles(str,tmp); ! 2268: sprintf(str,"%suser",cfg->data_dir); ! 2269: delfiles(str,tmp); ! 2270: ! 2271: sprintf(str,"%suser/ptrs/%04u.ixb",cfg->data_dir,user->number); /* msg ptrs */ ! 2272: remove(str); ! 2273: sprintf(str,"%smsgs/%04u.msg",cfg->data_dir,user->number); /* delete short msg */ ! 2274: remove(str); ! 2275: ! 2276: /* Update daily statistics database (for system and node) */ ! 2277: ! 2278: for(i=0;i<2;i++) { ! 2279: sprintf(str,"%sdsts.dab",i ? cfg->ctrl_dir : cfg->node_dir); ! 2280: if((file=nopen(str,O_RDWR))==-1) ! 2281: continue; ! 2282: memset(&stats,0,sizeof(stats)); ! 2283: lseek(file,4L,SEEK_SET); /* Skip timestamp */ ! 2284: read(file,&stats,sizeof(stats)); ! 2285: stats.nusers++; ! 2286: lseek(file,4L,SEEK_SET); ! 2287: write(file,&stats,sizeof(stats)); ! 2288: close(file); ! 2289: } ! 2290: ! 2291: return(0); ! 2292: } ! 2293: ! 2294: /* Returns length of specified user record 'field', or -1 if invalid */ ! 2295: int DLLCALL user_rec_len(int offset) ! 2296: { ! 2297: switch(offset) { ! 2298: ! 2299: /* Strings (of different lengths) */ ! 2300: case U_ALIAS: return(LEN_ALIAS); ! 2301: case U_NAME: return(LEN_NAME); ! 2302: case U_HANDLE: return(LEN_HANDLE); ! 2303: case U_NOTE: return(LEN_NOTE); ! 2304: case U_COMP: return(LEN_COMP); ! 2305: case U_COMMENT: return(LEN_COMMENT); ! 2306: case U_NETMAIL: return(LEN_NETMAIL); ! 2307: case U_ADDRESS: return(LEN_ADDRESS); ! 2308: case U_LOCATION: return(LEN_LOCATION); ! 2309: case U_ZIPCODE: return(LEN_ZIPCODE); ! 2310: case U_PASS: return(LEN_PASS); ! 2311: case U_PHONE: return(LEN_PHONE); ! 2312: case U_BIRTH: return(LEN_BIRTH); ! 2313: case U_MODEM: return(LEN_MODEM); ! 2314: ! 2315: /* Internal codes (16 chars) */ ! 2316: case U_CURSUB: ! 2317: case U_CURDIR: ! 2318: return (16); ! 2319: ! 2320: /* Dates in time_t format (8 hex digits) */ ! 2321: case U_LASTON: ! 2322: case U_FIRSTON: ! 2323: case U_EXPIRE: ! 2324: case U_PWMOD: ! 2325: case U_NS_TIME: ! 2326: case U_LOGONTIME: ! 2327: ! 2328: /* 32-bit integers (8 hex digits) */ ! 2329: case U_FLAGS1: ! 2330: case U_FLAGS2: ! 2331: case U_FLAGS3: ! 2332: case U_FLAGS4: ! 2333: case U_EXEMPT: ! 2334: case U_REST: ! 2335: case U_MISC: ! 2336: case U_QWK: ! 2337: case U_CHAT: ! 2338: ! 2339: /* Internal codes (8 chars) */ ! 2340: case U_CURXTRN: ! 2341: case U_XEDIT: ! 2342: case U_SHELL: ! 2343: return(8); ! 2344: ! 2345: /* 16-bit integers (5 decimal digits) */ ! 2346: case U_LOGONS: ! 2347: case U_LTODAY: ! 2348: case U_TIMEON: ! 2349: case U_TEXTRA: ! 2350: case U_TTODAY: ! 2351: case U_TLAST: ! 2352: case U_POSTS: ! 2353: case U_EMAILS: ! 2354: case U_FBACKS: ! 2355: case U_ETODAY: ! 2356: case U_PTODAY: ! 2357: case U_ULS: ! 2358: case U_DLS: ! 2359: return(5); ! 2360: ! 2361: /* 32-bit integers (10 decimal digits) */ ! 2362: case U_ULB: ! 2363: case U_DLB: ! 2364: case U_CDT: ! 2365: case U_MIN: ! 2366: case U_FREECDT: ! 2367: return(10); ! 2368: ! 2369: /* 3 char strings */ ! 2370: case U_TMPEXT: ! 2371: return(3); ! 2372: ! 2373: /* 2 digits integers (0-99) */ ! 2374: case U_LEVEL: ! 2375: case U_TL: ! 2376: case U_ROWS: ! 2377: case U_LEECH: /* actually, 2 hex digits */ ! 2378: return(2); ! 2379: ! 2380: /* Single digits chars */ ! 2381: case U_SEX: ! 2382: case U_PROT: ! 2383: return(1); ! 2384: } ! 2385: ! 2386: return(-1); ! 2387: } ! 2388: ! 2389: BOOL DLLCALL is_download_free(scfg_t* cfg, uint dirnum, user_t* user) ! 2390: { ! 2391: if(!VALID_CFG(cfg)) ! 2392: return(FALSE); ! 2393: ! 2394: if(dirnum>=cfg->total_dirs) ! 2395: return(FALSE); ! 2396: ! 2397: if(cfg->dir[dirnum]->misc&DIR_FREE) ! 2398: return(TRUE); ! 2399: ! 2400: if(user==NULL) ! 2401: return(FALSE); ! 2402: ! 2403: if(user->exempt&FLAG('D')) ! 2404: return(TRUE); ! 2405: ! 2406: if(cfg->dir[dirnum]->ex_ar==NULL || cfg->dir[dirnum]->ex_ar[0]==0) ! 2407: return(FALSE); ! 2408: ! 2409: return(chk_ar(cfg,cfg->dir[dirnum]->ex_ar,user)); ! 2410: } ! 2411: ! 2412: /****************************************************************************/ ! 2413: /* Add an IP address (with comment) to the IP filter/trashcan file */ ! 2414: /* ToDo: Move somewhere more appropriate (filter.c?) */ ! 2415: /****************************************************************************/ ! 2416: BOOL DLLCALL filter_ip(scfg_t* cfg, char* prot, char* reason, char* host ! 2417: ,char* ip_addr, char* username, char* fname) ! 2418: { ! 2419: char ip_can[MAX_PATH+1]; ! 2420: char tstr[64]; ! 2421: FILE* fp; ! 2422: time_t now=time(NULL); ! 2423: ! 2424: if(ip_addr==NULL) ! 2425: return(FALSE); ! 2426: ! 2427: sprintf(ip_can,"%sip.can",cfg->text_dir); ! 2428: if(fname==NULL) ! 2429: fname=ip_can; ! 2430: ! 2431: if((fp=fopen(fname,"a"))==NULL) ! 2432: return(FALSE); ! 2433: ! 2434: fprintf(fp,"\n; %s %s by %s on %s\n" ! 2435: ,prot,reason,username,timestr(cfg,&now,tstr)); ! 2436: ! 2437: if(host!=NULL) ! 2438: fprintf(fp,"; Hostname: %s\n",host); ! 2439: ! 2440: fprintf(fp,"%s\n",ip_addr); ! 2441: ! 2442: fclose(fp); ! 2443: return(TRUE); ! 2444: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.