home *** CD-ROM | disk | FTP | other *** search
- program TurboBBS100;
-
- (*******************************************************************)
- (* *)
- (* Turbo Bulletin Board System - Distribution Version 1.00 *)
- (* *)
- (* (c) 1985 by Robert H. Maxwell *)
- (* 201 - 2275 West 7th Avenue, *)
- (* Vancouver, British Columbia, CANADA *)
- (* V6K 1Y3 *)
- (* Original System running 300/1200 baud, 24hrs: (604) 738-7811 *)
- (* Written for a Kaypro 2-84 using Rixon 212A Intelligent modem *)
- (* *)
- (* If you like this program, it would most appreciated if you *)
- (* sent $30 to the above address. If you choose to operate a BBS *)
- (* with it, please forward the details so you can be kept up to *)
- (* date with changes to the program. *)
- (* *)
- (* Files required for compile: BBS.PAS (this file), *)
- (* IO.INC (machine dependent I/O) *)
- (* CLOCK.INC (real-time clock I/O) *)
- (* MAILSYS.INC (Sections named here) *)
- (* FILESYS.INC (XMODEM code here) *)
- (* *)
- (* Information files required: WELCOME.TXT (pre-sign-on message) *)
- (* BBSLIST.TXT (list of other BBS's) *)
- (* BBSHELP.TXT (command explanation) *)
- (* SYSINFO.TXT (info on the system) *)
- (* Message #1 is a permanent / MESS0001.TXT (Message Help file) *)
- (* message... do not delete! \ MESSAGES.BBS (Message table) *)
- (* FILES.BBS (Files table) *)
- (* Clear these periodically: / COMMENTS.BBS (Comments for Sysop) *)
- (* They can grow quickly... \ LOG.BBS (call log file) *)
- (* IDS.BBS (user list) *)
- (* *)
- (* .TXT files are WordStar editable; .BBS files are program data *)
- (* maintained by the program. *)
- (* User SYSOP is predeclared on IDS file: the password is TURBO *)
- (* *)
- (*******************************************************************)
-
- const
- clockin = true; { Compile-time flags: }
- sectsin = true; { Use to turn features on/off. }
-
- noecho = false;
- echo = true;
- null = #0;
- abort = #3;
- bell = #7;
- bksp = #8;
- tab = #9;
- lnfd = #10;
- cr = #13;
- pause = #19;
- esc = #27;
- space = ' ';
-
- type
- name = string[14];
- rate = (slow,fast);
- line = string[80];
- person = string[27];
- long = string[150];
- sysid = record
- user: person;
- exfl: byte;
- lsto: name;
- lstm: integer;
- pass: name;
- acc: byte;
- clr: name;
- bsp: char;
- lnf: char;
- upc: boolean;
- wid: byte;
- end;
- log = record
- who: integer;
- when: name;
- done: name;
- end;
- yesno = array[boolean] of string[3];
-
- const yn: yesno = ('NO','YES');
-
- var
- logfile: file of log;
- logrec: log;
- idfile: file of sysid;
- idrec: sysid;
- usernum: integer;
- caller: person;
- password,
- timeon,
- timeoff,
- cs,
- message: name;
- baud: rate;
- buffer: long;
- exitchar: char;
- access: byte;
- lastmess,
- charcount,
- lastspace,
- bufpointer,
- width: integer;
- controls,
- printon,
- local,
- filesopen,
- messopen,
- caps,
- expert: boolean;
- bl, lf, bs: char;
- sec, onsec, offsec : byte;
- min, onmin, offmin : byte;
- hour, onhour, offhour : byte;
- date, ondate, offdate : byte;
- month, onmonth, offmonth : byte;
- usesec, usemin, usehour : integer;
-
- {$I IO.INC}
- {$I CLOCK.INC}
-
- procedure outfile(fname: name);
-
- var
- wfile : text;
- fchar : char;
-
- begin
- assign(wfile,fname);
- {$I-} reset(wfile) {$I+};
- if IOresult <> 0 then lineout('Can''t find ' + fname + '!') else begin
- clearsc;
- repeat
- read(wfile, fchar);
- if fchar <> #$8D then begin { <-- Allows no-wrap using WordStar files}
- fchar := chr(ord(fchar) and 127);
- if fchar <> lnfd then charout(fchar);
- if fchar = cr then charout(lf);
- end;
- until cancelled or eof(wfile) or not cts;
- close(wfile);
- unload;
- end;
- end;
-
- function findid(caller: person): integer;
-
- var
- usernum: integer;
- index: integer;
-
- begin
- usernum := 0;
- index := 0;
- lineout('Searching userlist...');
- reset(idfile);
- if not eof(idfile) then begin
- repeat
- index := index + 1;
- read(idfile, idrec);
- if idrec.user = caller then usernum := index;
- until (usernum > 0) or eof(idfile);
- end;
- findid := usernum;
- end;
-
- {$I MAILSYS.INC}
- {$I FILESYS.INC}
-
- procedure definecs;
-
- var
- ch: char;
- prompt: line;
-
- begin
- ch := null;
- while cts and not (ch in ['Q','Y']) do begin
- lineout('The following input is NOT echoed until CR (RETURN) is pressed!');
- prompt := 'Enter character(s) that will clear your screen (end with CR): ';
- controls := true;
- cs := getinput(prompt, 11, noecho);
- controls := false;
- clearsc;
- ch := getcap(cr + lf + 'Did that do it (Y/N/Quit)? ');
- end;
- if ch = 'Q' then cs := lnfd;
- end;
-
- procedure definebs;
-
- begin
- repeat
- flush;
- controls := true;
- stringout('Type your backspace key: ');
- bs := charin(echo);
- controls := false;
- lineout(space);
- until not ((bs in [cr, tab, space, '0'..'9', 'A'..'Z', 'a'..'z']) and cts);
- end;
-
- procedure setwidth;
-
- var temp: name;
- test, innum: integer;
-
- begin
- repeat
- temp := getinput('Enter your terminal width (chars/line): ', 14, echo);
- val(temp, innum, test);
- until ((test=0) and (innum in [22..132])) or (temp='') or not cts;
- if test = 0 then width := innum;
- end;
-
- procedure setvideo;
-
- var loop: byte;
- inch: char;
- temp: name;
-
- function ctlchar(ch: char): name;
-
- begin
- if ch > #127 then ch := chr(ord(ch) and 127);
- case ch of
- null..#31 : ctlchar := '^' + chr(ord(ch) + 64);
- space..#126 : ctlchar := ch;
- #127 : ctlchar := '<DEL>';
- end;
- end;
-
- procedure dispcontrol(ch: char);
-
- begin
- if ch < #128 then stringout(ctlchar(ch))
- else stringout(ctlchar(ch) + '(with 8th bit set)');
- end;
-
- begin
- inch := '1';
- while (inch in ['1'..'9']) and cts do begin
- clearsc;
- lineout('Terminal parameters:' + cr + lf);
- lineout('1 - Upper case only: ' + yn[caps]);
- lineout('2 - Line feeds sent: ' + yn[lf = lnfd]);
- lineout('3 - Prompt bell ON : ' + yn[bl = bell]);
- stringout('4 - Backspace char.: ');
- dispcontrol(bs);
- lineout(space);
- stringout('5 - Clear Screen : ');
- for loop := 1 to length(cs) do dispcontrol(cs[loop]);
- lineout(space);
- str(width:3, temp);
- lineout('6 - Terminal width : ' + temp);
- lineout(space);
- inch := getcap('Enter number of parameter to change (0 to quit): ');
- case inch of
- '1': caps := not caps;
- '2': if lf = lnfd then lf := null else lf := lnfd;
- '3': if bl = bell then bl := null else bl := bell;
- '4': definebs;
- '5': definecs;
- '6': setwidth;
- end;
- end;
- lineout('New definitions will be saved when [G]oodbye is executed.');
- end;
-
- procedure getcomments;
-
- var
- comfile: file of line;
- linenum: integer;
- temp: line;
-
- begin
- clearsc;
- lineout('Enter comment: up to 15 lines, enter empty line to quit.');
- lineout(space);
- linenum := 0;
- assign(comfile, 'COMMENTS.BBS');
- reset(comfile);
- seek(comfile, filesize(comfile));
- temp := caller;
- if clockin then temp := temp + ' ' + timeon;
- write(comfile, temp);
- repeat
- linenum := linenum + 1;
- str(linenum:2, temp);
- stringout(temp + ': ');
- temp := inputstring(echo);
- if temp <> '' then write(comfile, temp);
- until (temp = '') or (linenum = 15) or not cts;
- close(comfile);
- end;
-
- function nextuser: integer;
-
- var temp: integer;
-
- begin
- stringout('Finding space for new user: ');
- temp := findid('***');
- if temp = 0 then nextuser := 1 + filesize(idfile) else nextuser := temp;
- end;
-
- procedure savedefaults;
-
- begin
- if usernum = 0 then usernum := nextuser;
- with idrec do begin
- user := caller;
- if expert then exfl := 0 else exfl := 255;
- if clockin then lsto := timeon;
- lstm := messtable[count].number;
- pass := password;
- clr := cs;
- acc := access;
- bsp := bs;
- lnf := lf;
- upc := caps;
- wid := width;
- end;
- seek(idfile, usernum - 1);
- write(idfile, idrec);
- end;
-
- procedure disconnect;
-
- var
- ch: char;
-
- begin
- clearsc;
- lineout('Answering question with other than "Y" or "N" returns to BBS:');
- ch := getcap('Do you want to leave comments to the Sysop (Y/N)? ');
- if ch = 'Y' then getcomments;
- if (ch = 'N') or (ch = 'Y') or not cts then begin
- connecttime;
- lineout('Thanks for calling, ' + caller);
- savedefaults;
- hangup;
- end;
- end;
-
- procedure chat;
-
- var
- count : byte;
- inch : char;
-
- begin
- inch := null;
- clearsc;
- lineout('Entering chat mode: CTL-C aborts at any time.');
- lineout('Summoning Sysop...');
- flush;
- count := 1;
- repeat
- count := count + 1;
- charout(bell);
- delay(1000);
- if inready then inch := charin(noecho);
- until (count > 10) or (inch <> null);
- while cts and (inch <> abort) do begin
- inch := charin(echo);
- if inch = cr then sendout(lf);
- end;
- end;
-
- procedure newpass;
-
- var
- temp : name;
- prompt : line;
-
- begin
- repeat
- prompt := 'Enter the password you want on this system: ';
- password := allcaps(getinput(prompt, 14,noecho));
- prompt := cr + lf + 'Enter it again, to be sure: ';
- temp := allcaps(getinput(prompt, 14, noecho));
- until (temp = password) or not cts;
- lineout('New password is saved when the [G]oodbye command is executed.');
- end;
-
- procedure listusers;
-
- var
- tempid: sysid;
- inch: name;
-
- begin
- if cts then begin
- clearsc;
- reset(idfile);
- repeat
- read(idfile,tempid);
- if access = 5 then begin
- str(tempid.acc:1, inch);
- stringout(inch + ' ');
- end;
- lineout(tempid.user);
- until eof(idfile) or cancelled or not cts;
- unload;
- end;
- end;
-
- procedure userlog;
-
- var
- call: person;
- loop: integer;
-
- begin
- if cts then begin
- clearsc;
- reset(logfile);
- while cts and (not cancelled) and not eof(logfile) do begin
- read(logfile,logrec);
- if logrec.who < 1 then call := ('Not on userlist')
- else call := getname(logrec.who);
- if clockin then for loop := length(call)+1 to 25 do call := call+space;
- stringout(call);
- if clockin then stringout(logrec.when + ' to ' + logrec.done);
- lineout(space);
- end;
- if access = 5 then begin
- if getcap('Kill (Y/N)? ') = 'Y' then rewrite(logfile);
- end;
- close(logfile);
- unload;
- end;
- end;
-
- procedure sysoponly;
-
- var
- inch : char;
- number: integer;
- temp: name;
- comment: line;
- comfile: file of line;
-
- begin
- if cts then begin
- clearsc;
- assign(comfile, 'COMMENTS.BBS');
- reset(comfile);
- while cts and (not cancelled) and not eof(comfile) do begin
- read(comfile,comment);
- lineout(comment);
- end;
- if getcap('Kill (Y/N)? ') = 'Y' then rewrite(comfile);
- close(comfile);
- unload;
- end;
- repeat
- number := getid('User name? ');
- if number > 0 then begin
- str(idrec.acc:2, temp);
- lineout('Access:' + temp);
- inch := getinput('New level? ', 1, echo);
- if inch in ['0'..'5'] then idrec.acc := integer(inch) - integer('0');
- reset(idfile);
- seek(idfile, number - 1);
- write(idfile, idrec);
- unload;
- end;
- until number = 0;
- end;
-
- procedure menu;
-
- begin
- if cts then begin
- cancelled := false;
- lineout(cr + lf + 'Information files:');
- lineout('[H]elp...... user[L]og... [O]thersys.. [U]serlist.. [W]elcome... s[Y]sinfo...');
- lineout(cr + lf + 'Message system:');
- lineout('[E]nter..... [K]ill...... [R]ead...... [S]can...... [#]:Status..');
- lineout(cr + lf + 'Functions:');
- lineout('[C]hat...... [F]iles..... [G]oodbye... [I]nstall... [P]assword.. e[X]pert....');
- end;
- end;
-
- procedure command;
-
- var
- prompt: line;
- inch : char;
- first : boolean;
-
- begin
- first := true;
- while cts do begin
- if first and not expert then menu;
- prompt := cr + lf + 'Command: ';
- if not expert
- then prompt := prompt + 'C,E,F,G,H,I,K,L,O,P,R,S,U,W,X,Y,# ? '
- else prompt := prompt + '(? for menu) ? ';
- flush;
- inch := getcap(prompt);
- first := true;
- case inch of
- 'K': deletex;
- 'E': enter;
- 'R': receive;
- 'S': quickscan;
- '#': begin status; showtime; connecttime; first := false; end;
- 'I': setvideo;
- 'F': filesys;
- 'G': disconnect;
- 'H': outfile('BBSHELP.TXT');
- 'Y': outfile('SYSINFO.TXT');
- 'W': outfile('WELCOME.TXT');
- '?': if expert then menu;
- 'X': begin expert := not expert; first := false; end;
- 'C': chat;
- 'U': listusers;
- 'L': userlog;
- 'O': outfile('BBSLIST.TXT');
- 'P': newpass;
- '@': if access=5 then sysoponly else first := false;
- '!': if access=5 then printon := not printon else first := false;
- else first := false;
- end; {case}
- end; {while cts}
- end; {command}
-
- procedure enterpass;
-
- var
- temp: name;
- tries: byte;
-
- begin
- tries := 0;
- lineout(space);
- repeat
- if tries > 0 then stringout('Incorrect - try again: ');
- tries := tries + 1;
- temp := allcaps(getinput('Enter your password: ', 14, noecho));
- until (temp = idrec.pass) or (tries = 3) or not cts;
- if (temp <> idrec.pass) then hangup;
- end;
-
- procedure getdefaults;
-
- begin
- enterpass;
- if cts then begin
- with idrec do begin
- password := pass;
- expert := (exfl = 0);
- access := acc;
- cs := clr;
- bs := bsp;
- lf := lnf;
- caps := upc;
- width := wid;
- lastmess := lstm;
- if clockin then lineout('Last on: ' + lsto);
- end;
- end;
- end;
-
- procedure newuser;
-
- begin
- lineout(cr + lf + 'Getting new user password & terminal info:');
- if cts then begin
- newpass;
- setvideo;
- access := 1;
- end;
- end;
-
- procedure signon(var caller: person);
-
- var ch: char;
-
- begin
- ch := space;
- repeat
- repeat
- caller := allcaps(getinput('What is your full name? ', 28, echo));
- until (length(caller) > 4) or not cts;
- if cts then begin
- usernum := findid(caller);
- if usernum=0 then ch:=getcap(caller + ': is this correct (Y/N)? ');
- end;
- until (usernum > 0) or (ch = 'Y') or not cts;
- if cts then begin
- if usernum = 0 then newuser else getdefaults;
- dispcaller;
- if access = 0 then begin
- lineout('User ' + caller + ' has been denied system access.');
- hangup;
- end;
- end;
- end;
-
- procedure logcall;
-
- begin
- reset(logfile);
- seek(logfile, filesize(logfile));
- with logrec do begin
- who := usernum;
- if clockin then begin
- when := timeon;
- done := timeoff;
- end;
- end;
- write(logfile, logrec);
- close(logfile);
- end;
-
- procedure defaults;
-
- begin
- lf := lnfd;
- bl := null;
- cs := lnfd;
- bs := bksp;
- expert := false;
- caps := false;
- width := 80;
- access := 1;
- assign(idfile, 'IDS.BBS');
- assign(logfile, 'LOG.BBS');
- lastmess := 0;
- caller := space;
- usernum := 0;
- messopen := false;
- filesopen := false;
- printon := false;
- inbuffer := '';
- cancelled := false;
- controls := false;
- end;
-
- begin
- exitchar := space;
- local := false;
- resetbuff;
- setup;
- defaults;
- awaitcall;
- repeat
- if clockin then begin
- clock(onmonth, ondate, onhour, onmin, onsec);
- timeon := time(onmonth, ondate, onhour, onmin, onsec);
- showtime;
- end;
- flush;
- if cts then outfile('WELCOME.TXT');
- if cts then signon(caller);
- if cts then initmess;
- if cts and (usernum > 0) then begin
- lineout('Checking for mail...');
- messagesearch(1,0,usernum,0);
- end;
- if cts then command;
- writeln('hung up...');
- if clockin then begin
- clock(offmonth, offdate, offhour, offmin, offsec);
- timeoff := time(offmonth, offdate, offhour, offmin, offsec);
- end;
- logcall;
- if messopen then closemess;
- close(idfile);
- unload;
- defaults;
- awaitcall;
- until exitchar = abort;
- end.
- əəəəəəə