home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************/
- /* log.c */
- /* */
- /* userlog code for Citadel bulletin board system */
- /************************************************************************/
-
- /************************************************************************/
- /* history */
- /* 83Jun13 BAK Modified terminate to handle rcpm flag correctly. */
- /* 83Jun11 BAK Fixed phantom configuration bug. */
- /* 83Feb27 CrT Fixed login-in-Mail> bug. */
- /* 83Feb26 CrT Limited # new messages for new users. */
- /* 83Feb18 CrT Null pw problem fixed. */
- /* 82Dec06 CrT 2.00 release. */
- /* 82Nov03 CrT Began local history file & general V1.2 cleanup */
- /************************************************************************/
-
- #include "b:210ctdl.h"
-
- /************************************************************************/
- /* contents */
- /* */
- /* crypte() encrypts/decrypts data blocks */
- /* getLog() loads requested userlog record */
- /* hash() hashes a string to an integer */
- /* login() is menu-level routine to log caller in */
- /* logInit() builds the RAM index to ctdllog.sys */
- /* newPW() is menu-level routine to change a PW */
- /* newUser() menu-level routine to log a new caller */
- /* noteLog() enters a userlog record into RAM index */
- /* putLog() stores a logBuffer into ctdllog.sys */
- /* PWSlot() returns userlog.buf slot password is in */
- /* slideLTab() support routine for sorting logTab */
- /* sortLog() sort userlog by time since last call */
- /* strCmpU() strcpm(), but ignoring case distinctions*/
- /* terminate() menu-level routine to exit system */
- /*??????userlog()?????? sysop special to display userlog */
- /* zapLogFile() erases & re-initializes ctdllog.sys */
- /************************************************************************/
-
- /************************************************************************/
- /* crypte() encrypts/decrypts data blocks */
- /* */
- /* This was at first using a full multiply/add pseudo-random sequence */
- /* generator, but 8080s don't like to multiply. Slowed down I/O */
- /* noticably. Rewrote for speed. */
- /* and subsequently removed to aide in debugging. */
- /************************************************************************/
- #define b fpc1
- #define c fi1
- #define s fi2
- crypte(buf, len, seed)
- char *buf;
- unsigned len, seed;
- {
- /* seed = (seed + cryptSeed) & 0xFF;
- b = buf;
- c = len;
- s = seed;
- for (; c; c--) {
- *b++ ^= s;
- s = (s + CRYPTADD) & 0xFF;
- }
- */
- }
-
- /************************************************************************/
- /* getLog() loads requested log record into RAM buffer */
- /************************************************************************/
- getLog(lBuf, n)
- struct logBuffer *lBuf;
- int n;
- {
- if (lBuf == &logBuf) thisLog = n;
-
- n *= SECSPERLOG;
-
- rseek(logfl, n, 0);
- if (rread(logfl, lBuf, SECSPERLOG) >= 1000) {
- printf("?getLog-rread fail");
- }
-
- crypte(lBuf, (SECSPERLOG*SECTSIZE), n); /* decode buffer */
- }
-
- /************************************************************************/
- /* hash() hashes a string to an integer */
- /************************************************************************/
- int hash(str)
- char *str;
- {
- char toUpper();
- int h, i, shift;
-
- for (h=shift=0; *str; shift=(shift+1)&7, str++) {
- h ^= (i=toUpper(*str)) << shift;
- }
- return h;
- }
-
- /************************************************************************/
- /* login() is the menu-level routine to log someone in */
- /************************************************************************/
- login(password)
- char *password; /* TRUE if parameters follow */
- {
- char getYesNo();
- int i, j;
- int foundIt, ltentry, match, ourSlot;
-
- foundIt = ((ltentry = PWSlot(password)) != ERROR);
-
- if (foundIt && *password) {
-
- /* recite caller's name, etc: */
- mPrintf(" %s\n", logBuf.lbname);
-
- /* update userlog entries: */
-
- loggedIn = TRUE;
- setUp(TRUE);
-
- showMessages(NEWoNLY, FALSE);
-
- listRooms(/* doDull== */ !expert);
-
- outFlag = OUTOK;
- if (
- (
- logBuf.lbId[MAILSLOTS-1]
- -
- (logBuf.lbvisit[ logBuf.lbgen[MAILROOM] & CALLMASK ]+1)
- < 0x8000
- )
- &&
- logBuf.lbId[MAILSLOTS-1] - oldestLo < 0x8000
- &&
- thisRoom != MAILROOM
- ) {
- mprintf("\n * You have private mail in Mail> *\n ");
- }
-
- } else {
- /* discourage password-guessing: */
- if (strLen(password) > 1) pause(2000);
- if (!unlogLoginOk && whichIO==MODEM) {
- mPrintf(" No record -- leave message to 'sysop' in Mail>\n ");
- } else if (getYesNo(" No record: Enter as new user")) newUser();
- }
- }
-
- /************************************************************************/
- /* logInit() indexes userlog.buf */
- /************************************************************************/
- logInit() {
- int i;
- int count;
-
- count = 0;
-
- /* clear logTab */
- for (i=0; i<MAXLOGTAB; i++) logTab[i].ltnewest = ERROR;
-
- /* load logTab: */
- for (thisLog=0; thisLog<MAXLOGTAB; thisLog++) {
- printf("log#%d\n", thisLog);
- getLog(&logBuf, thisLog);
-
- /* count valid entries: */
- if (logBuf.lbvisit[0] != ERROR) count++;
-
- /* copy relevant info into index: */
- logTab[thisLog].ltnewest = logBuf.lbvisit[0];
- logTab[thisLog].ltlogSlot= thisLog;
- logTab[thisLog].ltnmhash = hash(logBuf.lbname);
- logTab[thisLog].ltpwhash = hash(logBuf.lbpw );
- }
- printf(" logInit--%d valid log entries\n", count);
- sortLog();
- }
-
- /************************************************************************/
- /* newPW() is menu-level routine to change one's password */
- /* since some Citadel nodes run in public locations, we avoid */
- /* displaying passwords on the console. */
- /************************************************************************/
- newPW() {
- char oldPw[NAMESIZE];
- char pw[NAMESIZE];
- char *s;
- int i, goodPW;
-
- /* save password so we can find current user again: */
- strcpy(oldPw, logBuf.lbpw);
- storeLog();
- do {
- echo = CALLER;
- getString(" new password", pw, NAMESIZE);
- normalizeString(pw);
- echo = BOTH;
-
- /* check that PW isn't already claimed: */
- goodPW = (PWSlot(pw) == ERROR && strlen(pw) >= 2);
-
- if (!goodPW) mprintf("\n Poor password\n ");
-
- } while (
- (strlen(pw) < 2 || !goodPW )
- &&
- (haveCarrier || whichIO==CONSOLE)
- );
-
- doCR();
- PWSlot(oldPw); /* reload old log entry */
- pw[NAMESIZE-1] = 0x00; /* insure against loss of carrier: */
-
- if (goodPW && strlen(pw) > 1) { /* accept new PW: */
- strcpy(logBuf.lbpw, pw);
- logTab[0].ltpwhash = hash(pw);
- }
-
- mprintf("\n %s\n pw: ", logBuf.lbname);
- if (whichIO == CONSOLE) {
- printf("%s\n ", logBuf.lbpw);
- } else {
- s = logBuf.lbpw;
- while (*s) outMod(*s++);
- doCR();
- }
- }
-
- /************************************************************************/
- /* newUser() prompts for name and password */
- /************************************************************************/
- newUser() {
- char getYesNo();
- char fullnm[NAMESIZE];
- char pw[NAMESIZE];
- char *s;
- int good, g, h, i, ok, ourSlot, zero;
- unsigned low;
-
-
- configure(); /* make sure new users configure reasonably */
-
- if (!expert) tutorial("password.blb");
-
- do {
- /* get name and check for uniqueness... */
- do {
- getString(" Name", fullnm, NAMESIZE);
- normalizeString(fullnm);
- h = hash(fullnm);
- for (i=0, good=TRUE; i<MAXLOGTAB && good; i++) {
- if (h == logTab[i].ltnmhash) good = FALSE;
- }
- if (
- !h
- ||
- h==hash("Citadel")
- ||
- h==hash("Sysop")
- ) {
- good = FALSE;
- }
- /* lie sometimes -- hash collision !=> name collision */
- if (!good) mprintf("We already have a %s\n", fullnm);
- } while (!good && (haveCarrier || whichIO==CONSOLE));
-
- /* get password and check for uniqueness... */
- do {
- echo = CALLER;
- getString(" password", pw, NAMESIZE);
- normalizeString(pw);
- echo = BOTH ;
-
- h = hash(pw);
- for (i=0, good=strLen(pw) > 1; i<MAXLOGTAB && good; i++) {
- if (h == logTab[i].ltpwhash) good = FALSE;
- }
- if (!h) good = FALSE;
- if (!good) {
- mprintf("\n Poor password\n ");
- }
- } while( !good && (haveCarrier || whichIO==CONSOLE));
-
- mprintf("\n nm: %s", fullnm);
- mprintf("\n pw: ");
- if (whichIO == CONSOLE) {
- printf("%s\n ", pw);
- } else {
- echo = CALLER;
- mPrintf("%s\n ", pw);
- echo = BOTH;
- }
- } while (
- !getYesNo("OK")
- &&
- (haveCarrier || whichIO==CONSOLE)
- );
-
- if (ok && (haveCarrier || whichIO==CONSOLE)) {
-
- /* kick least recent caller out of userlog and claim entry: */
- ourSlot = logTab[MAXLOGTAB-1].ltlogSlot;
- slideLTab(0, MAXLOGTAB-1);
- logTab[0].ltlogSlot = ourSlot;
- getLog(&logBuf, ourSlot);
-
- /* copy info into record: */
- strcpy(logBuf.lbname, fullnm);
- strcpy(logBuf.lbpw, pw);
-
- low = newestLo-50;
- if (oldestLo-low < 0x8000) low = oldestLo;
- for (i=1; i<MAXVISIT; i++) logBuf.lbvisit[i]= low;
- logBuf.lbvisit[ 0]= newestLo;
- logBuf.lbvisit[ (MAXVISIT-1)]= oldestLo;
-
- /* initialize rest of record: */
- for (i=0; i<MAXROOMS; i++) {
- if (roomTab[i].rtflags & PUBLIC) {
- g = (roomTab[i].rtgen);
- logBuf.lbgen[i] = (g << GENSHIFT) + (MAXVISIT-1);
- } else {
- /* set to one less */
- g = (roomTab[i].rtgen + (MAXGEN-1)) % MAXGEN;
- logBuf.lbgen[i] = (g << GENSHIFT) + (MAXVISIT-1);
- }
- }
- for (i=0; i<MAILSLOTS; i++) {
- logBuf.lbslot[i] = 0;
- logBuf.lbId[ i] = oldestLo -1;
- }
-
- /* fill in logTab entries */
- logTab[0].ltpwhash = hash(pw) ;
- logTab[0].ltnmhash = hash(fullnm) ;
- logTab[0].ltlogSlot = thisLog ;
- logTab[0].ltnewest = logBuf.lbvisit[0];
-
- /* special kludge for Mail> room, to signal no new mail: */
- roomTab[MAILROOM].rtlastMessage = logBuf.lbId[MAILSLOTS-1];
-
- loggedIn = TRUE;
-
- storeLog();
-
- listRooms(/* doDull== */ !expert);
- }
- }
-
- /************************************************************************/
- /* noteLog() notes logTab entry in RAM buffer in master index */
- /************************************************************************/
- noteLog() {
- int i, j, slot;
-
- /* figure out who it belongs between: */
- for (i=0; logTab[i].ltnewest > logBuf.lbvisit[0]; i++);
-
- /* note location and open it up: */
- slot = i;
- slideltab(slot, MAXLOGTAB-1);
-
- /* insert new record */
- logTab[slot].ltnewest = logBuf.lbvisit[0] ;
- logTab[slot].ltlogSlot = thisLog ;
- logTab[slot].ltpwhash = hash(logBuf.lbpw) ;
- logTab[slot].ltnmhash = hash(logBuf.lbname);
- }
-
- /************************************************************************/
- /* putLog() stores givend log record into ctdllog.sys */
- /************************************************************************/
- putLog(lBuf, n)
- struct logBuffer *lBuf;
- int n;
- {
- n *= SECSPERLOG;
-
- crypte(lBuf, (SECSPERLOG*SECTSIZE), n); /* encode buffer */
-
- rseek(logfl, n, 0);
- if (rwrite(logfl, lBuf, SECSPERLOG) != SECSPERLOG) {
- printf("?putLog-rwrite fail");
- }
-
- crypte(lBuf, (SECSPERLOG*SECTSIZE), n); /* decode buffer */
- }
-
- /************************************************************************/
- /* PWSlot() returns userlog.buf slot password is in, else ERROR */
- /* NB: we also leave the record for the user in logBuf. */
- /************************************************************************/
- int PWSlot(pw)
- char pw[NAMESIZE];
- {
- int h, i;
- int foundIt, ourSlot;
-
- h = hash(pw);
-
- /* Check all passwords in memory: */
- for(i=0, foundIt=FALSE; !foundIt && i<MAXLOGTAB; i++) {
- /* check for password match here */
-
- /* If password matches, check full password */
- /* with current newUser code, password hash collisions should */
- /* not be possible... but this is upward compatable & cheap */
- if (logTab[i].ltpwhash == h) {
- ourSlot = logTab[i].ltlogSlot;
- getLog(&logBuf, ourSlot);
-
- if (strCmpU(pw, logBuf.lbpw) == SAMESTRING) {
- /* found a complete match */
- thisSlot = i ;
- foundIt = TRUE;
- }
- }
- }
- if (foundIt) return thisSlot;
- else return ERROR ;
- }
-
- /************************************************************************/
- /* slideLTab() slides bottom N lots in logTab down. For sorting. */
- /************************************************************************/
- slideLTab(slot, last)
- int slot;
- int last;
- {
- int i, j;
-
- /* open slot up: (movmem isn't guaranteed on overlaps) */
- for (i=last-1; i>=slot; i--) {
- movmem(&logTab[i], &logTab[i+1], sizeLTentry);
- }
- }
-
- /************************************************************************/
- /* sortLog ShellSorts userlog by time of last call */
- /************************************************************************/
- sortLog() {
- #define TSIZE 10
- char *temp[TSIZE];
- int finis, i, intCount, step;
-
- printf("sortLog...\n");
- if(sizeLTentry > TSIZE) {
- printf("!!!increase TSIZE in sortLog to %>d\n", sizeLTentry);
- }
-
- intCount = 0;
- for(finis=FALSE, step=MAXLOGTAB >> 1; !finis || step>1; ) {
- if (finis) {
- step = step/3 + 1;
- finis = FALSE;
- }
-
- finis = TRUE;
-
- printf("stepsize=%d\n", step);
-
- for(i=step; i<MAXLOGTAB; i++) {
- if(logTab[i-step].ltnewest < logTab[i].ltnewest) {
- intCount++;
- finis = FALSE;
-
- /* interchange two entries */
- movmem(&logTab[i-step], temp, sizeLTentry);
- movmem(&logTab[i], &logTab[i-step], sizeLTentry);
- movmem(temp, &logTab[i], sizeLTentry);
- }
- }
- }
- printf("sortLog: %d interchanges\n", intCount);
- }
-
- /************************************************************************/
- /* storeLog() stores the current log record. */
- /************************************************************************/
- storeLog() {
-
- logTab[0].ltnewest = newestLo;
-
- logBuf.lbvisit[0] = newestLo;
- logBuf.lbwidth = termWidth;
- logBuf.lbnulls = termNulls;
- logBuf.lbflags = expert | termUpper | termLF | termTab | aide;
-
- if (loggedIn) putLog(&logBuf, thisLog); /*<<<<added test */
- }
-
- /************************************************************************/
- /* strCmpU() is strcmp(), but ignoring case distinctions */
- /************************************************************************/
- int strCmpU(s, t)
- char s[], t[];
- {
- char toUpper();
- int i;
-
- i = 0;
-
- while (toUpper(s[i]) == toUpper(t[i])) {
- if (s[i++] == '\0') return 0;
- }
- return toUpper(s[i]) - toUpper(t[i]);
- }
-
- /************************************************************************/
- /* terminate() is menu-level routine to exit system */
- /************************************************************************/
- terminate(discon)
- char discon;
- /* 1. parameter <discon> is TRUE or FALSE. */
- /* 2. if <discon> is TRUE, breaks modem connection */
- /* or switches whichIO from CONSOLE to MODEM, */
- /* as appropriate. */
- /* 3. modifies externs: struct logBuf, */
- /* struct logTab */
- /* 4. returns no values */
- /* modified dvm 9-82 */
- {
- if (loggedIn) {
- mprintf(" %s logged out\n ", logBuf.lbname);
-
- logBuf.lbgen[thisRoom] = roomBuf.rbgen << GENSHIFT;
- if (haveCarrier || onConsole) storeLog();
- loggedIn = FALSE;
-
- setUp(TRUE);
- }
-
- if (discon) {
- switch (whichIO) {
- case MODEM:
- if (rcpm) {
- writeSysTab();
- exitToCpm = TRUE;
- } else interpret(pHangUp);
- break;
- case CONSOLE:
- whichIO = MODEM;
- printf("\n'MODEM' mode.\n ");
- break;
- }
- }
- }
-
- /************************************************************************/
- /* zapLogFile() erases & re-initializes userlog.buf */
- /************************************************************************/
- zapLogFile() {
- char getCh(), toUpper();
- int i;
-
- printf("\nWipe out log file? ");
- if (toUpper(getCh()) != 'Y') return;
-
- /* clear RAM buffer out: */
- logBuf.lbvisit[0] = ERROR;
- for (i=0; i<MAILSLOTS; i++) {
- logBuf.lbslot[i]= ERROR;
- logBuf.lbId[i] = ERROR;
- }
- for (i=0; i<NAMESIZE; i++) {
- logBuf.lbname[i]= 0;
- logBuf.lbpw[i] = 0;
- }
-
- /* write empty buffer all over file; */
- for (i=0; i<MAXLOGTAB; i++) {
- putLog(&logBuf, i);
- }
- }
-