|
|
1.1 ! root 1: /* data.cpp */ ! 2: ! 3: /* Synchronet data access routines */ ! 4: ! 5: /* $Id: data.cpp,v 1.20 2006/04/05 09:45:21 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: /**************************************************************/ ! 39: /* Functions that store and retrieve data from disk or memory */ ! 40: /**************************************************************/ ! 41: ! 42: #include "sbbs.h" ! 43: ! 44: /****************************************************************************/ ! 45: /* Looks for close or perfect matches between str and valid usernames and */ ! 46: /* numbers and prompts user for near perfect matches in names. */ ! 47: /* Returns the number of the matched user or 0 if unsuccessful */ ! 48: /* Called from functions main_sec, useredit and readmailw */ ! 49: /****************************************************************************/ ! 50: uint sbbs_t::finduser(char *instr) ! 51: { ! 52: int file,i; ! 53: char str[128],str2[256],str3[256],ynq[25],c,pass=1; ! 54: ulong l,length; ! 55: FILE *stream; ! 56: ! 57: i=atoi(instr); ! 58: if(i>0) { ! 59: username(&cfg, i,str2); ! 60: if(str2[0] && strcmp(str2,"DELETED USER")) ! 61: return(i); } ! 62: strcpy(str,instr); ! 63: strupr(str); ! 64: sprintf(str3,"%suser/name.dat",cfg.data_dir); ! 65: if(flength(str3)<1L) ! 66: return(0); ! 67: if((stream=fnopen(&file,str3,O_RDONLY))==NULL) { ! 68: errormsg(WHERE,ERR_OPEN,str3,O_RDONLY); ! 69: return(0); } ! 70: sprintf(ynq,"%.2s",text[YN]); ! 71: ynq[2]='Q'; ! 72: ynq[3]=0; ! 73: length=filelength(file); ! 74: while(pass<3) { ! 75: fseek(stream,0L,SEEK_SET); /* seek to beginning for each pass */ ! 76: for(l=0;l<length;l+=LEN_ALIAS+2) { ! 77: if(!online) break; ! 78: fread(str2,LEN_ALIAS+2,1,stream); ! 79: for(c=0;c<LEN_ALIAS;c++) ! 80: if(str2[c]==ETX) break; ! 81: str2[c]=0; ! 82: if(!c) /* deleted user */ ! 83: continue; ! 84: strcpy(str3,str2); ! 85: strupr(str2); ! 86: if(pass==1 && !strcmp(str,str2)) { ! 87: fclose(stream); ! 88: return((l/(LEN_ALIAS+2))+1); } ! 89: if(pass==2 && strstr(str2,str)) { ! 90: bprintf(text[DoYouMeanThisUserQ],str3 ! 91: ,(uint)(l/(LEN_ALIAS+2))+1); ! 92: c=(char)getkeys(ynq,0); ! 93: if(sys_status&SS_ABORT) { ! 94: fclose(stream); ! 95: return(0); } ! 96: if(c==text[YN][0]) { ! 97: fclose(stream); ! 98: return((l/(LEN_ALIAS+2))+1); } ! 99: if(c=='Q') { ! 100: fclose(stream); ! 101: return(0); } } } ! 102: pass++; } ! 103: bputs(text[UnknownUser]); ! 104: fclose(stream); ! 105: return(0); ! 106: } ! 107: ! 108: /****************************************************************************/ ! 109: /* Returns the number of user transfers in XFER.IXT for either a dest user */ ! 110: /* source user, or filename. */ ! 111: /****************************************************************************/ ! 112: int sbbs_t::getuserxfers(int fromuser, int destuser, char *fname) ! 113: { ! 114: char str[256]; ! 115: int file,found=0; ! 116: FILE *stream; ! 117: ! 118: sprintf(str,"%sxfer.ixt",cfg.data_dir); ! 119: if(!fexist(str)) ! 120: return(0); ! 121: if(!flength(str)) { ! 122: remove(str); ! 123: return(0); } ! 124: if((stream=fnopen(&file,str,O_RDONLY))==NULL) { ! 125: errormsg(WHERE,ERR_OPEN,str,O_RDONLY); ! 126: return(0); } ! 127: while(!ferror(stream)) { ! 128: if(!fgets(str,81,stream)) ! 129: break; ! 130: str[22]=0; ! 131: if(fname!=NULL && fname[0] && !strncmp(str+5,fname,12)) ! 132: found++; ! 133: else if(fromuser && atoi(str+18)==fromuser) ! 134: found++; ! 135: else if(destuser && atoi(str)==destuser) ! 136: found++; } ! 137: fclose(stream); ! 138: return(found); ! 139: } ! 140: ! 141: /****************************************************************************/ ! 142: /* Fills the timeleft variable with the correct value. Hangs up on the */ ! 143: /* user if their time is up. */ ! 144: /* Called from functions main_sec and xfer_sec */ ! 145: /****************************************************************************/ ! 146: void sbbs_t::gettimeleft(void) ! 147: { ! 148: char str[128]; ! 149: char tmp[512]; ! 150: int i; ! 151: time_t thisevent; ! 152: long tleft; ! 153: struct tm tm, last_tm; ! 154: ! 155: now=time(NULL); ! 156: ! 157: if(localtime_r(&now,&tm)==NULL) ! 158: memset(&tm,0,sizeof(tm)); ! 159: if(useron.exempt&FLAG('T')) { /* Time online exemption */ ! 160: timeleft=cfg.level_timepercall[useron.level]*60; ! 161: if(timeleft<10) /* never get below 10 for exempt users */ ! 162: timeleft=10; ! 163: } else { ! 164: tleft=(((long)cfg.level_timeperday[useron.level]-useron.ttoday) ! 165: +useron.textra)*60L; ! 166: if(tleft<0) tleft=0; ! 167: if(tleft>cfg.level_timepercall[useron.level]*60) ! 168: tleft=cfg.level_timepercall[useron.level]*60; ! 169: tleft+=useron.min*60L; ! 170: tleft-=now-starttime; ! 171: if(tleft>0x7fffL) ! 172: timeleft=0x7fff; ! 173: else ! 174: timeleft=tleft; ! 175: } ! 176: ! 177: /* Timed event time reduction handler */ ! 178: ! 179: event_time=0; ! 180: for(i=0;i<cfg.total_events;i++) { ! 181: if(!cfg.event[i]->node || cfg.event[i]->node>cfg.sys_nodes ! 182: || cfg.event[i]->misc&EVENT_DISABLED) ! 183: continue; ! 184: if(!(cfg.event[i]->misc&EVENT_FORCE) ! 185: || (!(cfg.event[i]->misc&EVENT_EXCL) && cfg.event[i]->node!=cfg.node_num) ! 186: || !(cfg.event[i]->days&(1<<tm.tm_wday)) ! 187: || (cfg.event[i]->mdays!=0 && !(cfg.event[i]->mdays&(1<<tm.tm_mday)))) ! 188: continue; ! 189: ! 190: tm.tm_hour=cfg.event[i]->time/60; ! 191: tm.tm_min=cfg.event[i]->time%60; ! 192: tm.tm_sec=0; ! 193: tm.tm_isdst=-1; /* Do not adjust for DST */ ! 194: thisevent=mktime(&tm); ! 195: ! 196: if(localtime_r(&cfg.event[i]->last,&last_tm)==NULL) ! 197: memset(&last_tm,0,sizeof(last_tm)); ! 198: ! 199: if(tm.tm_mday==last_tm.tm_mday && tm.tm_mon==last_tm.tm_mon) ! 200: thisevent+=24L*60L*60L; /* already ran today, so add 24hrs */ ! 201: if(!event_time || thisevent<event_time) { ! 202: event_time=thisevent; ! 203: event_code=cfg.event[i]->code; ! 204: } ! 205: } ! 206: if(event_time && now+(time_t)timeleft>event_time) { /* less time, set flag */ ! 207: if(event_time<now) ! 208: timeleft=0; ! 209: else ! 210: timeleft=event_time-now; ! 211: if(!(sys_status&SS_EVENT)) { ! 212: lprintf(LOG_NOTICE,"Node %d Time reduced (to %s) due to upcoming event (%s) on %s" ! 213: ,cfg.node_num,sectostr(timeleft,tmp),event_code,timestr(&event_time)); ! 214: sys_status|=SS_EVENT; ! 215: } ! 216: } ! 217: ! 218: if((long)timeleft<0) /* timeleft can't go negative */ ! 219: timeleft=0; ! 220: if(thisnode.status==NODE_NEWUSER) { ! 221: timeleft=cfg.level_timepercall[cfg.new_level]; ! 222: if(timeleft<10*60L) ! 223: timeleft=10*60L; ! 224: } ! 225: ! 226: if(gettimeleft_inside) /* The following code is not recursive */ ! 227: return; ! 228: gettimeleft_inside=1; ! 229: ! 230: if(!timeleft && !SYSOP && !(sys_status&SS_LCHAT)) { ! 231: logline(nulstr,"Ran out of time"); ! 232: SAVELINE; ! 233: if(sys_status&SS_EVENT) ! 234: bprintf(text[ReducedTime],timestr(&event_time)); ! 235: bputs(text[TimesUp]); ! 236: if(!(sys_status&(SS_EVENT|SS_USERON)) && useron.cdt>=100L*1024L ! 237: && !(cfg.sys_misc&SM_NOCDTCVT)) { ! 238: sprintf(tmp,text[Convert100ktoNminQ],cfg.cdt_min_value); ! 239: if(yesno(tmp)) { ! 240: logline(" ","Credit to Minute Conversion"); ! 241: useron.min=adjustuserrec(&cfg,useron.number,U_MIN,10,cfg.cdt_min_value); ! 242: useron.cdt=adjustuserrec(&cfg,useron.number,U_CDT,10,-(102400L)); ! 243: sprintf(str,"Credit Adjustment: %ld",-(102400L)); ! 244: logline("$-",str); ! 245: sprintf(str,"Minute Adjustment: %u",cfg.cdt_min_value); ! 246: logline("*+",str); ! 247: RESTORELINE; ! 248: gettimeleft(); ! 249: gettimeleft_inside=0; ! 250: return; ! 251: } ! 252: } ! 253: if(cfg.sys_misc&SM_TIME_EXP && !(sys_status&SS_EVENT) ! 254: && !(useron.exempt&FLAG('E'))) { ! 255: /* set to expired values */ ! 256: bputs(text[AccountHasExpired]); ! 257: sprintf(str,"%s Expired",useron.alias); ! 258: logentry("!%",str); ! 259: if(cfg.level_misc[useron.level]&LEVEL_EXPTOVAL ! 260: && cfg.level_expireto[useron.level]<10) { ! 261: useron.flags1=cfg.val_flags1[cfg.level_expireto[useron.level]]; ! 262: useron.flags2=cfg.val_flags2[cfg.level_expireto[useron.level]]; ! 263: useron.flags3=cfg.val_flags3[cfg.level_expireto[useron.level]]; ! 264: useron.flags4=cfg.val_flags4[cfg.level_expireto[useron.level]]; ! 265: useron.exempt=cfg.val_exempt[cfg.level_expireto[useron.level]]; ! 266: useron.rest=cfg.val_rest[cfg.level_expireto[useron.level]]; ! 267: if(cfg.val_expire[cfg.level_expireto[useron.level]]) ! 268: useron.expire=now ! 269: +(cfg.val_expire[cfg.level_expireto[useron.level]]*24*60*60); ! 270: else ! 271: useron.expire=0; ! 272: useron.level=cfg.val_level[cfg.level_expireto[useron.level]]; } ! 273: else { ! 274: if(cfg.level_misc[useron.level]&LEVEL_EXPTOLVL) ! 275: useron.level=cfg.level_expireto[useron.level]; ! 276: else ! 277: useron.level=cfg.expired_level; ! 278: useron.flags1&=~cfg.expired_flags1; /* expired status */ ! 279: useron.flags2&=~cfg.expired_flags2; /* expired status */ ! 280: useron.flags3&=~cfg.expired_flags3; /* expired status */ ! 281: useron.flags4&=~cfg.expired_flags4; /* expired status */ ! 282: useron.exempt&=~cfg.expired_exempt; ! 283: useron.rest|=cfg.expired_rest; ! 284: useron.expire=0; ! 285: } ! 286: putuserrec(&cfg,useron.number,U_LEVEL,2,ultoa(useron.level,str,10)); ! 287: putuserrec(&cfg,useron.number,U_FLAGS1,8,ultoa(useron.flags1,str,16)); ! 288: putuserrec(&cfg,useron.number,U_FLAGS2,8,ultoa(useron.flags2,str,16)); ! 289: putuserrec(&cfg,useron.number,U_FLAGS3,8,ultoa(useron.flags3,str,16)); ! 290: putuserrec(&cfg,useron.number,U_FLAGS4,8,ultoa(useron.flags4,str,16)); ! 291: putuserrec(&cfg,useron.number,U_EXPIRE,8,ultoa(useron.expire,str,16)); ! 292: putuserrec(&cfg,useron.number,U_EXEMPT,8,ultoa(useron.exempt,str,16)); ! 293: putuserrec(&cfg,useron.number,U_REST,8,ultoa(useron.rest,str,16)); ! 294: if(cfg.expire_mod[0]) ! 295: exec_bin(cfg.expire_mod,&main_csi); ! 296: RESTORELINE; ! 297: gettimeleft(); ! 298: gettimeleft_inside=0; ! 299: return; ! 300: } ! 301: SYNC; ! 302: hangup(); ! 303: } ! 304: gettimeleft_inside=0; ! 305: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.