home *** CD-ROM | disk | FTP | other *** search
- const
- numsects = 12;
- maxlength = 24;
- maxlenstr = '24';
-
- type
- messages = record
- number: integer;
- sender: integer;
- recver: integer;
- subject: name;
- date: name;
- private: boolean;
- section: byte;
- repto: integer;
- reply: integer;
- recved: boolean;
- end;
- sectname = array[1..numsects] of string[20];
- messtext = array[1..maxlength] of line;
-
- const
- sect : sectname = ('1: General',
- '2: Ohio Scientific',
- '3: CP/M',
- '4: Buy and Sell',
- '5: 6502',
- '6: Turbo Pascal',
- '7: C',
- '8: CompuServe',
- '9: 6809',
- '10: Kaypro',
- '11: MS-DOS',
- '12: TurboBBS code');
-
- maxmess = 52; { <-- Maximum number of messages - this limit due to CP/M
- maximum directory size on Kaypro.}
-
- var
- messagefile: file of messages;
- count: integer;
- messtable: array[1..maxmess] of messages;
- preformat: boolean;
-
- function namemess(number: integer): name;
-
- var
- filename: name;
-
- begin
- str((10000 + number):6, filename);
- namemess := messdrive + 'MESS' + copy(filename, 3, 4) + '.TXT';
- end;
-
- procedure kill(x: integer);
-
- var
- victim: text;
-
- begin
- assign(victim, namemess(x));
- erase(victim);
- end;
-
- function secure(tabloc: byte): boolean;
-
- begin
- with messtable[tabloc] do
- secure := ((usernum <> sender)
- and (usernum <> recver)
- and (access < sysop))
- or (usernum = 0);
- end;
-
- procedure listsections;
-
- var
- loopvar : integer;
- temp : line;
-
- begin
- if cts then begin
- clearsc;
- lineout('Sections:' + cr + lf);
- for loopvar := 1 to numsects do begin
- lineout(sect[loopvar]);
- end;
- end;
- end;
-
- procedure status;
-
- var
- temp: line;
-
- begin
- if cts then begin
- lineout(cr + lf + 'Caller: ' + caller);
- str(access:1, temp);
- lineout('Access level: ' + temp);
- str(count:2, temp);
- lineout('System has ' + temp + ' messages;');
- str(nextmess:4, temp);
- lineout('Next message is: ' + temp);
- end;
- end;
-
- procedure initmess;
-
- begin
- if cts then lineout(cr + lf + 'Initializing message system...');
- count := 0;
- nextmess := 1;
- assign(messagefile, 'MESSAGES.BBS');
- {$I-} reset(messagefile) {$I+};
- if IOresult = 0 then begin
- while (count < maxmess) and not eof(messagefile) do begin
- count := count + 1;
- read(messagefile, messtable[count]);
- end;
- close(messagefile);
- if count > 0 then nextmess := messtable[count].number + 1;
- end;
- unload;
- messopen := true;
- status;
- end;
-
- function findmessage(x: integer): byte;
-
- var
- loop: byte;
-
- begin
- loop := 0;
- findmessage := 0;
- if count > 0 then begin
- repeat
- loop := loop + 1;
- until (loop >= count) or (messtable[loop].number >= x);
- if messtable[loop].number = x
- then findmessage := loop
- else findmessage := 0;
- end;
- end;
-
- function getname(usernum: integer): person;
-
- var
- tempid: sysid;
-
- begin
- seek(idfile, usernum-1);
- read(idfile, tempid);
- getname := tempid.user;
- end;
-
- procedure header(tabloc: byte);
-
- var
- temp: line;
-
- begin
- if cts then with messtable[tabloc] do begin
- str(number:4, temp);
- stringout(cr + lf);
- if private then stringout('Private ');
- stringout('Message #' + temp);
- temp := getname(sender);
- stringout(' is from: ' + temp);
- if recver > 0 then temp := getname(recver) else temp := 'ALL';
- if recved then temp := temp + ' (Rec''d)';
- lineout(' to: ' + temp);
- stringout('Subj: ' + subject);
- if clockin then stringout(' Time: ' + date);
- if sectsin then stringout(' Section ' + sect[section]);
- lineout(space);
- end;
- end;
-
- procedure destroy(tabloc: byte);
-
- var
- loop: byte;
-
- begin
- if tabloc > 0 then begin
- kill(messtable[tabloc].number);
- for loop := tabloc+1 to count do
- messtable[loop-1] := messtable[loop];
- count := count - 1;
- lineout('Message deleted.');
- end;
- end;
-
- procedure readfile(tabloc: byte);
-
- begin
- if cts then begin
- outfile(namemess(messtable[tabloc].number));
- lineout(space);
- if (messtable[tabloc].recver = usernum) and (usernum > 0)
- then messtable[tabloc].recved := true;
- if cts and (tabloc > 1) and not secure(tabloc) then begin
- if getcap('Delete (Y/N)? ') = 'Y' then destroy(tabloc);
- end;
- end;
- end;
-
- procedure readmess(number: integer);
-
- var tabloc: byte;
-
- begin
- tabloc := findmessage(number);
- if tabloc = 0 then lineout('Message not found.')
- else if (secure(tabloc) and messtable[tabloc].private)
- then lineout('Private message.')
- else begin
- header(tabloc);
- readfile(tabloc);
- end;
- end;
-
- procedure delmessage(x: integer);
-
- var
- tabloc: byte;
-
- begin;
- tabloc := findmessage(x);
- if cts then begin
- if tabloc > 0 then begin
- if not secure(tabloc) then begin
- header(tabloc);
- if getcap('Are you sure (Y/N)? ') = 'Y' then destroy(tabloc);
- end
- else lineout('You can''t delete that message.');
- end
- else lineout('Message not found.');
- end;
- end;
-
- function getid(prompt: line): integer;
-
- var
- temp: person;
-
- begin
- temp := allcaps(getinput(prompt, 28, echo));
- if temp = '' then getid := 0 else getid := findid(temp);
- end;
-
- procedure deletex;
-
- begin
- if cts then delmessage(getint(nextmess - 1, 0, 'Delete: which number? '));
- end;
-
- procedure quickscan;
-
- var
- loop: byte;
- first: integer;
-
- begin
- if cts then begin
- first := getint(nextmess - 1, lastmess + 1, 'Start scan at which number (* for new)? ');
- if first > 0 then begin
- clearsc;
- for loop := 1 to count do
- if (messtable[loop].number >= first)
- and not (secure(loop) and messtable[loop].private)
- and cts and not cancelled
- then header(loop);
- end;
- end;
- end;
-
- procedure readind;
-
- var
- messnum: integer;
- tabloc : byte;
-
- begin
- repeat
- messnum := getint(nextmess - 1, 0, 'Read which number (enter 0 to quit)? ');
- if messnum > 0 then readmess(messnum);
- until (messnum <= 0) or not cts;
- end;
-
- procedure messagesearch(first:byte; fromnum, tonum:integer; sectnum:byte);
-
- var
- loop: byte;
- inch: char;
- oldnum: integer;
- matched: boolean;
-
- begin
- matched := false;
- inch := null;
- loop := first;
- while cts and (loop <= count) and (inch <> 'Q') and (count <> 0) do begin
- oldnum := messtable[loop].number;
- if ((fromnum = 0) or (fromnum = messtable[loop].sender))
- and ((tonum = 0) or (tonum = messtable[loop].recver))
- and ((sectnum = 0) or (sectnum = messtable[loop].section))
- and not (secure(loop) and messtable[loop].private)
- then begin
- matched := true;
- cancelled := false;
- header(loop);
- inch := getcap('Read (Y/N/Quit)? ');
- if inch = 'Y' then readfile(loop);
- end;
- if messtable[loop].number = oldnum then loop := loop + 1;
- end;
- if cts and not matched then lineout('No messages found.');
- end;
-
- function findfirst(startmess: integer): byte;
-
- var loop : byte;
-
- begin
- loop := 0;
- if count > 0 then repeat
- loop := loop + 1;
- until (messtable[loop].number >= startmess) or (loop = count);
- findfirst := loop;
- end;
-
- function getfirst: byte;
-
- var
- startmess : integer;
-
- begin
- repeat
- startmess := getint(nextmess - 1, lastmess + 1, 'Start at which message (? for stats, * for new)? ');
- if startmess = -1 then status;
- until (startmess <> -1) or not cts;
- if startmess = 0 then getfirst := 0
- else getfirst := findfirst(startmess);
- end;
-
- procedure readfrom;
-
- var
- fromnum: integer;
- first: byte;
-
- begin
- if cts then begin
- fromnum := getid('Enter name of sender: ');
- if fromnum < 1
- then stringout('Not a registered user name.')
- else begin
- first := getfirst;
- if first > 0 then messagesearch(first, fromnum, 0, 0);
- end;
- end;
- end;
-
- procedure readto;
-
- var
- tonum: integer;
- first: byte;
-
- begin
- if cts then begin
- tonum := getid('Enter name of addressee: ');
- if tonum < 1
- then stringout('Not a registered user name.')
- else begin
- first := getfirst;
- if first > 0 then messagesearch(first, 0, tonum, 0);
- end;
- end;
- end;
-
- procedure readsect;
-
- var
- first: byte;
- inch: integer;
-
- begin
- if cts then repeat
- if sectsin then
- inch := getint(numsects, 0, 'Enter section number (0 for all, ? for list): ')
- else inch := 1;
- case inch of
- -1 : listsections;
- 0..numsects: begin
- first := getfirst;
- if first > 0 then messagesearch(first, 0, 0, inch);
- end;
- end;
- until (inch <> -1) or not cts;
- end;
-
- procedure receive;
-
- var
- uchar: char;
-
- begin
- if cts then begin
- clearsc;
- if not expert then outfile(readmenu);
- repeat
- uchar := getcap('Read mode: (A,I,F,T,S, or ? for menu)? ');
- if uchar = '?' then outfile(readmenu);
- until (uchar in ['A','I','F','T','S',cr]) or not cts;
- if uchar = 'I' then readind;
- if cts and (uchar <> 'I') then begin
- case uchar of
- 'A': messagesearch(getfirst,0,0,0);
- 'F': readfrom;
- 'T': readto;
- 'S': readsect;
- end;
- end;
- end;
- end;
-
- procedure closemess;
-
- var
- loop: byte;
-
- begin
- rewrite(messagefile);
- for loop := 1 to count do
- write(messagefile, messtable[loop]);
- close(messagefile);
- messopen := false;
- end;
-
- {make "enter" an overlay procedure and make filesys another one to save space}
- procedure enter;
-
- var
- tabloc: byte;
- messbuff: messtext;
- linenum: byte;
- inch: char;
-
- procedure compose(var block: messtext; var linenum: byte);
-
- var
- temp: name;
-
- begin
- lineout(cr + lf + 'Enter message text: ' + maxlenstr + ' lines of 80 chars max.');
- lineout('An empty line ends entry. "." at start of line forces new line.');
- lineout(space);
- if linenum < maxlength then repeat
- linenum := linenum + 1;
- str(linenum:2, temp);
- stringout(temp + ': ');
- block[linenum] := inputstring(echo);
- until (linenum = maxlength) or (block[linenum] = '') or not cts;
- if block[linenum] = '' then linenum := linenum - 1;
- end;
-
- procedure list(var block: messtext; first, last: byte);
-
- var
- loop: byte;
- temp: name;
-
- begin
- if (first > 0) and (last > 0) and cts then begin
- loop := first;
- while (loop <= last) and (not cancelled) and cts do begin
- str(loop:2, temp);
- stringout(temp + ': ');
- lineout(block[loop]);
- loop := loop + 1;
- end;
- lineout(space);
- end;
- end;
-
- procedure delline(var block: messtext; linenum: byte; var maxline: byte);
-
- var temp: char;
- loop: byte;
-
- begin
- list(block, linenum, linenum);
- if cts and (linenum > 0) then begin
- temp := getcap('Delete: are you sure (Y/N)? ');
- if temp = 'Y' then begin
- for loop := linenum+1 to maxline do block[loop-1] := block[loop];
- block[maxline] := '';
- maxline := pred(maxline);
- lineout('Line deleted.');
- end;
- end;
- end;
-
- procedure edit(var block: messtext; linenum: byte);
-
- var
- oldstring: line;
- newstring: line;
- posn : integer;
-
- begin
- if (linenum > 0) and cts then begin
- list(block, linenum, linenum);
- oldstring := getinput('Enter string to replace: ', 80, echo);
- newstring := getinput('Enter replacement: ', 80, echo);
- posn := pos(oldstring, block[linenum]);
- if posn <> 0 then begin
- delete(block[linenum], posn, length(oldstring));
- insert(newstring, block[linenum], posn);
- list(block, linenum, linenum);
- end
- else lineout('Old string not found.');
- lineout(space);
- end;
- end;
-
- procedure replace(var block: messtext; linenum: byte);
-
- begin
- if (linenum > 0) and cts then begin
- lineout('Old line:');
- list(block, linenum, linenum);
- lineout('Enter new line:');
- stringout('? ');
- block[linenum] := inputstring(echo);
- end;
- end;
-
- function whichline(linenum: byte): byte;
-
- var
- temp: name;
- x : integer;
-
- begin
- str(linenum:2, temp);
- x := getint(linenum, 0, ' Which line? (1 - ' + temp + ')? ');
- if (x <= 0) or not cts then whichline := 0 else whichline := x;
- end;
-
- procedure newheader(var entry: messages);
-
- var
- temp, tonum: integer;
-
- begin
- if cts then begin
- entry.sender := usernum;
- tonum := getid('Who to (RETURN or ENTER key for ALL)? ');
- if tonum = 0 then lineout('Message to: ALL');
- entry.recver := tonum;
- entry.subject := getinput('Subject (14 characters max.)? ', 14, echo);
- if clockin then begin
- clock(month, date, hour, min, sec);
- entry.date := time(month, date, hour, min, sec);
- end;
- if sectsin then repeat
- temp := getint(numsects, 0, 'Which section (or "?" for list)? ');
- if temp = -1 then listsections;
- if temp in [1..numsects] then entry.section := temp;
- until (temp in [1..numsects]) or not cts
- else entry.section := 1;
- if tonum > 0 then entry.private := getcap('Private message (Y/N)? ')='Y'
- else entry.private := false;
- entry.reply := 0;
- entry.repto := 0;
- entry.number := nextmess;
- entry.recved := false;
- end;
- end;
-
- procedure storemess(var block: messtext; tabloc, lastline: byte);
-
- var
- outfile: text;
- linenum: byte;
-
- begin
- if cts then begin
- lineout('Writing message to disk...');
- assign(outfile, namemess(nextmess));
- rewrite(outfile);
- linenum := 1;
- while linenum <= lastline do begin
- if (copy(block[linenum],1,1) = '.') or preformat then begin
- writeln(outfile);
- if not preformat then
- block[linenum] := copy(block[linenum], 2, length(block[linenum])-1);
- end
- else write(outfile, ' ');
- write(outfile, block[linenum]);
- linenum := linenum + 1;
- end;
- writeln(outfile);
- close(outfile);
- unload;
- nextmess := nextmess + 1;
- count := count + 1;
- end;
- end;
-
- begin
- preformat := false;
- if cts then begin
- clearsc;
- if access < reg then lineout('You cannot enter messages yet: Use [A]pply command.')
- else begin
- tabloc := count + 1;
- if tabloc > maxmess then lineout('No message space left.')
- else begin
- repeat
- newheader(messtable[tabloc]);
- header(tabloc);
- inch := getcap('Is this OK (Y/N/Abort)? ');
- until (inch <> 'N') or not cts;
- unload;
- if inch <> 'A' then begin
- linenum := 0;
- compose(messbuff, linenum);
- if not expert then outfile(editmenu);
- repeat
- inch := getcap('Edit command: A,C,D,E,L,P,R,S or ? for menu? ');
- case inch of
- 'C': compose(messbuff, linenum);
- 'D': delline(messbuff, whichline(linenum), linenum);
- 'E': edit(messbuff, whichline(linenum));
- 'L': list(messbuff, whichline(linenum), linenum);
- 'P': begin preformat := true; storemess(messbuff, tabloc, linenum); end;
- 'R': replace(messbuff, whichline(linenum));
- 'S': storemess(messbuff, tabloc, linenum);
- '?': outfile(editmenu);
- end;
- until (inch = 'A')
- or (inch = 'S')
- or (inch = 'P')
- or not cts;
- end;
- end; {2nd else}
- end; {1st else}
- end; {if cts}
- end; {enter}