|
|
1.1 root 1: /* data.cpp */
2:
3: /* Synchronet data access routines */
4:
5: /* $Id: data.cpp,v 1.5 2000/12/11 23:21:11 rswindell Exp $ */
6:
7: /****************************************************************************
8: * @format.tab-size 4 (Plain Text/Source Code File Header) *
9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
10: * *
11: * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html *
12: * *
13: * This program is free software; you can redistribute it and/or *
14: * modify it under the terms of the GNU General Public License *
15: * as published by the Free Software Foundation; either version 2 *
16: * of the License, or (at your option) any later version. *
17: * See the GNU General Public License for more details: gpl.txt or *
18: * http://www.fsf.org/copyleft/gpl.html *
19: * *
20: * Anonymous FTP access to the most recent released source is available at *
21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
22: * *
23: * Anonymous CVS access to the development source and modification history *
24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: *
25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
26: * (just hit return, no password is necessary) *
27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
28: * *
29: * For Synchronet coding style and modification guidelines, see *
30: * http://www.synchro.net/source.html *
31: * *
32: * You are encouraged to submit any modifications (preferably in Unix diff *
33: * format) via e-mail to [email protected] *
34: * *
35: * Note: If this box doesn't appear square, then you need to fix your tabs. *
36: ****************************************************************************/
37:
38: /**************************************************************/
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 files in the directory 'dirnum' */
110: /****************************************************************************/
111: int sbbs_t::getfiles(uint dirnum)
112: {
113: char str[256];
114: long l;
115:
116: sprintf(str,"%s%s.ixb",cfg.dir[dirnum]->data_dir, cfg.dir[dirnum]->code);
117: l=flength(str);
118: if(l>0L)
119: return(l/F_IXBSIZE);
120: return(0);
121: }
122:
123: /****************************************************************************/
124: /* Returns the number of user transfers in XFER.IXT for either a dest user */
125: /* source user, or filename. */
126: /****************************************************************************/
127: int sbbs_t::getuserxfers(int fromuser, int destuser, char *fname)
128: {
129: char str[256];
130: int file,found=0;
131: FILE *stream;
132:
133: sprintf(str,"%sxfer.ixt",cfg.data_dir);
134: if(!fexist(str))
135: return(0);
136: if(!flength(str)) {
137: remove(str);
138: return(0); }
139: if((stream=fnopen(&file,str,O_RDONLY))==NULL) {
140: errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
141: return(0); }
142: while(!ferror(stream)) {
143: if(!fgets(str,81,stream))
144: break;
145: str[22]=0;
146: if(fname!=NULL && fname[0] && !strncmp(str+5,fname,12))
147: found++;
148: else if(fromuser && atoi(str+18)==fromuser)
149: found++;
150: else if(destuser && atoi(str)==destuser)
151: found++; }
152: fclose(stream);
153: return(found);
154: }
155:
156: /****************************************************************************/
157: /* Returns the number of files in the database for 'dir' */
158: /****************************************************************************/
159: uint sbbs_t::gettotalfiles(uint dirnum)
160: {
161: char str[81];
162:
163: sprintf(str,"%s%s.ixb", cfg.dir[dirnum]->data_dir, cfg.dir[dirnum]->code);
164: return((uint)(flength(str)/F_IXBSIZE));
165: }
166:
167:
168: /****************************************************************************/
169: /* Fills the timeleft variable with the correct value. Hangs up on the */
170: /* user if their time is up. */
171: /* Called from functions main_sec and xfer_sec */
172: /****************************************************************************/
173: void sbbs_t::gettimeleft(void)
174: {
175: char str[128];
176: char tmp[512];
177: int i;
178: time_t eventtime=0;
179: time_t thisevent;
180: long tleft;
181: struct tm *tm, last_tm;
182:
183: now=time(NULL);
184:
185: tm=localtime(&now);
186: if(tm==NULL)
187: return;
188: if(useron.exempt&FLAG('T')) { /* Time online exemption */
189: timeleft=cfg.level_timepercall[useron.level]*60;
190: if(timeleft<10) /* never get below 10 for exempt users */
191: timeleft=10; }
192: else {
193: tleft=(((long)cfg.level_timeperday[useron.level]-useron.ttoday)
194: +useron.textra)*60L;
195: if(tleft<0) tleft=0;
196: if(tleft>cfg.level_timepercall[useron.level]*60)
197: tleft=cfg.level_timepercall[useron.level]*60;
198: tleft+=useron.min*60L;
199: tleft-=now-starttime;
200: if(tleft>0x7fffL)
201: timeleft=0x7fff;
202: else
203: timeleft=tleft; }
204:
205: /* Timed event time reduction handler */
206:
207: for(i=0;i<cfg.total_events;i++) {
208: if(!cfg.event[i]->node || cfg.event[i]->node>cfg.sys_nodes)
209: continue;
210: if(!(cfg.event[i]->misc&EVENT_FORCE)
211: || (!(cfg.event[i]->misc&EVENT_EXCL) && cfg.event[i]->node!=cfg.node_num)
212: || !(cfg.event[i]->days&(1<<tm->tm_wday)))
213: continue;
214:
215: tm=gmtime(&cfg.event[i]->last);
216: if(tm)
217: last_tm=*tm;
218: else
219: memset(&last_tm,0,sizeof(last_tm));
220: tm=gmtime(&now);
221: if(tm==NULL)
222: return;
223: tm->tm_hour=cfg.event[i]->time/60; /* hasn't run yet today */
224: tm->tm_min=cfg.event[i]->time-(tm->tm_hour*60);
225: tm->tm_sec=0;
226: thisevent=mktime(tm);
227: if(tm->tm_mday==last_tm.tm_mday && tm->tm_mon==last_tm.tm_mon)
228: thisevent+=24L*60L*60L; /* already ran today, so add 24hrs */
229: if(!eventtime || thisevent<eventtime)
230: eventtime=thisevent;
231: }
232: if(eventtime && now+(time_t)timeleft>eventtime) { /* less time, set flag */
233: sys_status|=SS_EVENT;
234: timeleft=eventtime-now; }
235:
236: /* Event time passed by front-end */
237: if(next_event && (next_event<now || next_event-now<(time_t)timeleft)) {
238: timeleft=next_event-now;
239: sys_status|=SS_EVENT; }
240:
241: if(timeleft<0) /* timeleft can't go negative */
242: timeleft=0;
243: if(thisnode.status==NODE_NEWUSER) {
244: timeleft=cfg.level_timepercall[cfg.new_level];
245: if(timeleft<10*60L)
246: timeleft=10*60L; }
247:
248: if(gettimeleft_inside) /* The following code is not recursive */
249: return;
250: gettimeleft_inside=1;
251:
252: if(!timeleft && !SYSOP && !(sys_status&SS_LCHAT)) {
253: logline(nulstr,"Ran out of time");
254: SAVELINE;
255: if(sys_status&SS_EVENT)
256: bputs(text[ReducedTime]);
257: bputs(text[TimesUp]);
258: if(!(sys_status&(SS_EVENT|SS_USERON)) && useron.cdt>=100L*1024L
259: && !(cfg.sys_misc&SM_NOCDTCVT)) {
260: sprintf(tmp,text[Convert100ktoNminQ],cfg.cdt_min_value);
261: if(yesno(tmp)) {
262: logline(" ","Credit to Minute Conversion");
263: useron.min=adjustuserrec(&cfg,useron.number,U_MIN,10,cfg.cdt_min_value);
264: useron.cdt=adjustuserrec(&cfg,useron.number,U_CDT,10,-(102400L));
265: sprintf(str,"Credit Adjustment: %ld",-(102400L));
266: logline("$-",str);
267: sprintf(str,"Minute Adjustment: %u",cfg.cdt_min_value);
268: logline("*+",str);
269: RESTORELINE;
270: gettimeleft();
271: gettimeleft_inside=0;
272: return; } }
273: if(cfg.sys_misc&SM_TIME_EXP && !(sys_status&SS_EVENT)
274: && !(useron.exempt&FLAG('E'))) {
275: /* set to expired values */
276: bputs(text[AccountHasExpired]);
277: sprintf(str,"%s Expired",useron.alias);
278: logentry("!%",str);
279: if(cfg.level_misc[useron.level]&LEVEL_EXPTOVAL
280: && cfg.level_expireto[useron.level]<10) {
281: useron.flags1=cfg.val_flags1[cfg.level_expireto[useron.level]];
282: useron.flags2=cfg.val_flags2[cfg.level_expireto[useron.level]];
283: useron.flags3=cfg.val_flags3[cfg.level_expireto[useron.level]];
284: useron.flags4=cfg.val_flags4[cfg.level_expireto[useron.level]];
285: useron.exempt=cfg.val_exempt[cfg.level_expireto[useron.level]];
286: useron.rest=cfg.val_rest[cfg.level_expireto[useron.level]];
287: if(cfg.val_expire[cfg.level_expireto[useron.level]])
288: useron.expire=now
289: +(cfg.val_expire[cfg.level_expireto[useron.level]]*24*60*60);
290: else
291: useron.expire=0;
292: useron.level=cfg.val_level[cfg.level_expireto[useron.level]]; }
293: else {
294: if(cfg.level_misc[useron.level]&LEVEL_EXPTOLVL)
295: useron.level=cfg.level_expireto[useron.level];
296: else
297: useron.level=cfg.expired_level;
298: useron.flags1&=~cfg.expired_flags1; /* expired status */
299: useron.flags2&=~cfg.expired_flags2; /* expired status */
300: useron.flags3&=~cfg.expired_flags3; /* expired status */
301: useron.flags4&=~cfg.expired_flags4; /* expired status */
302: useron.exempt&=~cfg.expired_exempt;
303: useron.rest|=cfg.expired_rest;
304: useron.expire=0; }
305: putuserrec(&cfg,useron.number,U_LEVEL,2,ultoa(useron.level,str,10));
306: putuserrec(&cfg,useron.number,U_FLAGS1,8,ultoa(useron.flags1,str,16));
307: putuserrec(&cfg,useron.number,U_FLAGS2,8,ultoa(useron.flags2,str,16));
308: putuserrec(&cfg,useron.number,U_FLAGS3,8,ultoa(useron.flags3,str,16));
309: putuserrec(&cfg,useron.number,U_FLAGS4,8,ultoa(useron.flags4,str,16));
310: putuserrec(&cfg,useron.number,U_EXPIRE,8,ultoa(useron.expire,str,16));
311: putuserrec(&cfg,useron.number,U_EXEMPT,8,ultoa(useron.exempt,str,16));
312: putuserrec(&cfg,useron.number,U_REST,8,ultoa(useron.rest,str,16));
313: if(cfg.expire_mod[0])
314: exec_bin(cfg.expire_mod,&main_csi);
315: RESTORELINE;
316: gettimeleft();
317: gettimeleft_inside=0;
318: return; }
319: SYNC;
320: hangup(); }
321: gettimeleft_inside=0;
322: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.