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