E#include #include "fido.h" #include "fidomem.h" #include "proto.h" /* Handle LASTUSER.BBS files, that communicate with external programs. read_lastuser() If enabled, load LASTUSER.BBS (if no taskID) or LASTUSRn.BBS and after sanity checking, update last-read pointers from the external program. write_lastuser() Generates a LASTUSER.BBS or LASTUSRn.BBS file and a SCHED.BBS, presumably at logoff. */ /* Version 11 callers record (modified). */ #define OLDMAXLREAD 10 struct _usr { char name[36]; /* users ASCII name, */ char city[36]; /* city and state, */ /* This structure takes exactly 40 bytes, and replaces the old first date. (Which was luckily int[20] by mistake!) */ struct { int area; /* message area */ int msg; /* last msg read */ } lastmsg[OLDMAXLREAD]; char pwd[16]; /* what else, */ int times; /* # times called, */ int help; /* last help setting, */ int tabs; /* 1 == expand tabs, */ int nulls; /* number of nulls after CR, */ int msg; /* last selected message area, */ int more; /* last MORE setting, */ int priv; /* user privelege level, */ char ldate[20]; /* last time called, */ int time; /* total time on system in 1 day, */ unsigned bits; /* various bit flags, */ unsigned upld; /* total K byte uploaded, */ unsigned dnld; /* total K bytes downloaded, */ unsigned dnldl; /* download, for limiting, */ int files; /* last selected file area, */ char width; /* screen width, */ char len; /* screen length, */ int credit; /* credit, in cents, */ int debit; /* debit, in cents, */ /* These are NOT part of the Fido 11 caller record; they were added simply to provide the extra info needed for various utilities. */ /* 180 bytes */ int next_event; /* time til next event (0 - 1440 mins) or -1 */ unsigned baud; /* callers last baud rate */ unsigned tleft; /* time remaining this call (0 for sysop) */ char lang; /* language selection */ char extra_byte; /* RESERVED */ unsigned extra[14]; /* oh, something for later */ }; /* Version 11 scheduler structure. */ #define OLDSCHEDS (5 * DAYS_WK) /* size of time table */ struct _oldsched { struct { int year,month,day,daywk; int hour,mins,sec; } time; int len; int enable; /* 1 == enabled -1 == disabled 0 == deleted */ int trigger; int result; /* returned value */ char tag; /* schedule tag */ int a,b,c,d,e; }; /* Read LASTUSER and update the in-memory caller record. */ void read_lastuser() { struct _usr user; int f,i; char fname[SS],buff[SS]; #define OLDAREA (user.lastmsg[i].area) #define OLDMSG (user.lastmsg[i].msg) #define CLRAREA (caller.lastmsg[j].area) #define CLRMSG (caller.lastmsg[j].msg) if (! fbit(FBIT_V11)) return; /* not enabled */ if (taskid) maketid(buff,"LASTUSR.BBS"); else strcpy(buff,"LASTUSER.BBS"); makesname(fname,buff); /* in system path */ f= open(fname,0); if (f == -1) return; /* doesnt exist */ read(f,&user,sizeof(struct _usr)); /* read it in */ close(f); if (! same(user.name,caller.name)) return; if (user.times != caller.times) return; /* must be same call */ /* Old: areas run 1 - N, 0 means unallocated. New: areas run 0 - 254, 255 means unallocated. */ cprintf(SM+104,fname); /* "Updating caller record from fn" */ for (i= 0; i < OLDMAXLREAD; i++) { if (OLDAREA == 0) continue; /* ignore blank spots */ setlmsg(OLDMSG,OLDAREA - 1); /* store number */ } } /* Locate the specified stored area, or a free slot, and save new highest read message and area. */ static setlmsg(n,a) int n; /* msg number */ int a; /* area number */ { int i,m; m= -1; /* remember first free slot */ /* Look for the desired area # in the table; also remember the first unused slot in case we dont find the one we want. */ for (i= 0; i < MAXLREAD; i++) { if ((caller.lastmsg[i].area == 255) && (m == -1)) m= i; if (caller.lastmsg[i].area == a) break; } if (i >= MAXLREAD) { /* if area was not found */ if (m == -1) m= 0; /* (bug prevention) */ i= m; /* slot to use this time */ if (++m >= MAXLREAD) m= 0; /* turn next slot into */ caller.lastmsg[m].area= 255; /* free slot */ caller.lastmsg[m].msg= 0; } caller.lastmsg[i].area= a; /* set area number */ caller.lastmsg[i].msg= n; /* set new number */ } /* Generate a LASTUSER.BBS file. */ void write_lastuser() { char *cp,fname[SS],buff[SS]; int i; struct _usr user; if (! fbit(FBIT_V11)) return; /* not enabled */ eventsys(); /* generate a SCHED.BBS file */ for (cp= (char *) &user, i= sizeof(struct _usr); i--;) *cp++= 0; strproc(user.name,caller.name,99); /* fixed-format name */ strcpy(user.city,caller.city); strcpy(user.pwd,caller.pwd); strcpy(user.ldate,caller.date); /* Old: areas run 1 - N, 0 means unallocated. New: areas run 0 - 254, 255 means unallocated. */ for (i= 0; i < OLDMAXLREAD; i++) { /* last read msg stuff */ if (caller.lastmsg[i].area != 0) { user.lastmsg[i].area= caller.lastmsg[i].area + 1; user.lastmsg[i].msg= caller.lastmsg[i].msg; } } switch (uval(CLR_PRV,CLR_PRVS)) { /* translate priv */ case 0: user.priv= -1; break; /* TWIT */ case 2: user.priv= 2; break; /* NORMAL */ case 3: user.priv= 4; break; /* PRIVEL */ case 4: user.priv= 6; break; /* EXTRA */ case 7: user.priv= 10; break; /* SYSOP */ default: case 1: user.priv= 0; break; /* DISGRACE */ } switch (uval(CLR_HLP,CLR_HLPS)) { /* translate help */ case 0: user.help= 2; break; case 1: user.help= 4; break; case 2: default: user.help= 6; break; } user.width= uval(CLR_WID,CLR_WIDS); user.len= uval(CLR_LEN,CLR_LENS); user.nulls= uval(CLR_NUL,CLR_NULS); user.more= uval(CLR_LEN,CLR_LENS) ? 1 : 0; user.tabs= 1; user.msg= caller.msg; user.files= caller.files; user.time= caller.time; user.times= caller.times; user.dnld= caller.dnld; user.dnldl= caller.dnldl; user.upld= caller.upld; user.credit= caller.credit; user.debit= caller.debit; /* Now fill in the extra, non-fido-11 stuff. */ user.baud= caller.baud; /* last-used baud rate */ user.tleft= caller.tleft; /* time remaining this call */ user.lang= uval(CLR_LAN,CLR_LANS); /* current language */ i= til_sched('/',caller.tleft,0); /* if an event within limit, */ if (i >= 0) user.next_event= til_event(i); /* report it */ else user.next_event= -1; if (taskid) maketid(buff,"LASTUSR.BBS"); /* filename for output */ else strcpy(buff,"LASTUSER.BBS"); makesname(fname,buff); /* in system path */ i= creat(fname,1); if (i == -1) { mprintf(CM+151,fname); /* "cant create filename" */ lprintf(LM+39,fname); return; } write(i,&user,sizeof(struct _usr)); close(i); } /* Generate a version 11 SCHED.BBS file, putting in it only those events that are currently enabled. */ static eventsys() { struct _oldsched o; int f,i,t; char *cp,fname[SS]; makesname(fname,"SCHED.BBS"); /* make pathname */ f= creat(fname,2); if (i == -1) { mprintf(CM+151,fname); /* "cant create filename" */ lprintf(LM+39,fname); return; } for (cp= (char *) &o, i= sizeof(struct _oldsched); i--;) *cp++= 0; /* clear it out, */ for (i= t= 0; i < SCHEDS; i++) { if (! fido.sched[i].tag) break; /* end of table */ if (! event_on(i)) continue; /* only enabled ones */ o.enable= 1; o.time.daywk= fido.sched[i].daywk; o.time.hour= fido.sched[i].hr; o.time.mins= fido.sched[i].min; o.tag= fido.sched[i].tag; o.len= fido.sched[i].len; o.result= fido.sched[i].result; o.trigger= fido.sched[i].swtch; /* N.A. in v11 ... */ write(f,&o,sizeof(struct _oldsched)); ++t; } o.tag= o.enable= 0; while (t < OLDSCHEDS) { write(f,&o,sizeof(struct _oldsched)); ++t; } close(f); } /* Return true if this event is enabled and ours.*/ static event_on(i) int i; { struct _sched *sc; sc= &fido.sched[i]; /* keep it simple! */ if ((sc-> tag < 'A') || (sc-> tag > 'X')) return(0); /* must be a runnable event */ if (sc-> taskid && (sc-> taskid != taskid)) return(0); /* only our task ID */ if (sc-> swtch) { /* if a switch specified, */ if (! istoggle(sc-> swtch - 1)) return(0); /* it must be on */ } return(1); }