home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
mbug
/
mbug184.arc
/
ROS34.LBR
/
ROSMSG.IZC
/
ROSMSG.INC
Wrap
Text File
|
1979-12-31
|
16KB
|
508 lines
{ ROSMSG.INC - Remote Operating System Message Sub-system }
overlay procedure mesg_enter(to_ctrl: char);
{ Enter a new message }
type
TextPtr = ^TextRecord;
TextRecord =
record
LineNo : integer; { Line number }
TextMsg : message; { Summary index }
next : TextPtr { Pointer to next element on list }
end;
var
stop_msg: boolean;
msg_status: record_status;
ch: char;
last_line, to_loc: integer;
TextBase, TextLast, this: TextPtr;
to_fn: firstname;
to_ln: lastname;
subj: subject;
key: StrName;
temp_user_rec: user_list;
procedure mesg_input(var last_line: integer);
{ Input message }
var
ch: char;
this: TextPtr;
msg: StrStd;
begin
Writeln(USR);
msg := ' ';
next_inpstr := '';
while (not brk) and (msg <> '') do
begin
msg := next_inpstr;
Write(USR, last_line:2, '> ');
GetStr(msg, ch, len_msg, 'AEW');
Writeln(USR);
if msg <> ''
then if MaxAvail > 256
then
begin
new(this);
if TextBase = nil
then TextBase := this
else TextLast^.next := this;
TextLast := this;
TextLast^.LineNo := last_line;
TextLast^.TextMsg := msg;
TextLast^.next := nil;
last_line := succ(last_line)
end
else
begin
Writeln(USR, 'Insufficient memory to continue message entry.');
msg := ''
end
end
end;
procedure mesg_edit;
{ Edit selected line from message }
var
ch: char;
i: integer;
this: TextPtr;
msg: StrStd;
begin
Writeln(USR);
i := strint(prompt('Line number', 2, 'E'));
this := TextBase;
while (i <> this^.LineNo) and (this <> nil) do
this := this^.next;
if this <> nil
then
begin
msg := this^.TextMsg;
Write(USR, i:2, '> ');
GetStr(msg, ch, len_msg, 'AEW');
Writeln(USR);
if msg <> ''
then this^.TextMsg := msg;
end
else Writeln(USR, 'Line not found.')
end;
procedure mesg_print;
{ Display message currently being edited }
var
this: TextPtr;
begin
Writeln(USR, 'From: ', user_rec.fn, ' ', user_rec.ln);
if to_fn = ''
then Writeln(USR, ' To: ALL')
else Writeln(USR, ' To: ', to_fn, ' ', to_ln);
Writeln(USR, ' Re: ', subj);
Writeln(USR);
this := TextBase;
while (not brk) and (this <> nil) do
begin
Writeln(USR, this^.LineNo:2, ': ', this^.TextMsg);
this := this^.next
end
end;
procedure mesg_save(to_loc: integer; subj: subject; var stop_msg: boolean);
{ Save message to disk }
var
start, line_count: integer;
this: TextPtr;
file_time: tad_array;
str: StrTAD;
begin
Writeln(USR);
if (msg_status = private) and (user_rec.access >= val_acc) and (valid_pw)
then if ask('Do you want this message to be public')
then msg_status := public;
start := filesize(mesg_file);
seek(mesg_file, start);
line_count := 0;
this := TextBase;
while this <> nil do
begin
Write(mesg_file, this^.TextMsg);
line_count := succ(line_count);
this := this^.next
end;
if line_count > 0
then
begin
GetTAD(file_time);
str := FormTAD(file_time);
seek(summ_file, 0);
read(summ_file, summ_rec);
with summ_rec do
begin
date := file_time;
status := msg_status;
area := AreaSet;
num := succ(num);
num_prev := 0;
num_next := 0;
user_from := user_loc;
user_to := to_loc;
subject := subj;
st_rec := start;
size := line_count
end;
seek(summ_file, 0);
Write(summ_file, summ_rec);
seek(summ_file, filesize(summ_file));
Write(summ_file, summ_rec);
mesg_insert(2);
case msg_status of
private: Write(USR, 'Private');
public: Write(USR, 'Public')
end;
Writeln(USR, ' message ', summ_rec.num, ' filed ', str)
end
else Writeln(USR, 'Empty message not filed.');
stop_msg := TRUE
end;
procedure mesg_quit(var stop_msg: boolean);
{ Return to command mode }
begin
Writeln(USR);
Writeln(USR, 'Message not filed.');
stop_msg := TRUE
end;
begin { mesg_enter }
if user_rec.access < val_acc
then list('D');
Writeln(USR);
Writeln(USR, 'From: ', user_rec.fn, ' ', user_rec.ln);
OK := FALSE;
msg_status := private;
repeat
if (user_rec.access < val_acc) or
(to_ctrl = 'S') or
((to_ctrl = 'A') and (summ_rec.user_from = 0))
then
begin
to_fn := 'SYSOP';
Writeln(USR, ' To: ', to_fn)
end
else if (to_ctrl = 'A') and (summ_rec.user_from > 0)
then
begin
to_loc := summ_rec.user_from;
OK := TRUE;
GetRec(DatF, to_loc, temp_user_rec);
to_fn := temp_user_rec.fn;
to_ln := temp_user_rec.ln;
Writeln(USR, ' To: ', to_fn, ' ', to_ln)
end
else to_fn := prompt('To FIRST name [C/R for ALL]', len_fn, 'ES');
if to_fn = ''
then
begin
to_loc := 0;
msg_status := public;
OK := TRUE
end
else if to_fn = 'SYSOP'
then to_ln := ''
else if to_ctrl <> 'A'
then to_ln := prompt('LAST name', len_ln, 'ES');
if not OK
then
begin
key := pad(to_ln, len_ln) + pad(to_fn, len_fn);
FindKey(IdxF, to_loc, key);
if not OK
then Writeln(USR, to_fn, ' ', to_ln, ' not known on system.')
end
until (not online) or OK;
if not valid_pw
then
begin
subj := 'Password problem';
Writeln(USR, ' Re: ', subj)
end
else if user_rec.access < val_acc
then
begin
subj := 'New user';
Writeln(USR, ' Re: ', subj)
end
else subj := prompt('Subject', len_subj, 'E');
Writeln(USR);
Writeln(USR, 'To return to command mode, enter an empty line.');
Writeln(USR, 'Ready for message...');
TextBase := nil;
last_line := 1;
mesg_input(last_line);
stop_msg := FALSE;
repeat
Writeln(USR);
case select('Edit command', 'ContinueEditListSaveQuit') of
'C': mesg_input(last_line);
'E': mesg_edit;
'L': mesg_print;
'S': mesg_save(to_loc, subj, stop_msg);
'Q': mesg_quit(stop_msg);
'?': list('E')
end
until (not online) or stop_msg;
while TextBase <> nil do
begin
this := TextBase; { Get rid of list elements }
TextBase := TextBase^.next;
dispose(this)
end
end;
overlay procedure mesg_quick_scan;
{ Print abbreviated summary of messages }
var
private: boolean;
sep: char;
num, line_count: integer;
begin
line_count := 0;
private := FALSE;
num := mesg_start('Start');
MesgCurr := MesgBase;
while (MesgCurr <> nil) and (MesgCurr^.MesgNo < num) do
MesgCurr := MesgCurr^.next;
Writeln(USR);
while (not brk) and (MesgCurr <> nil) do
begin
if (MesgCurr^.TypMsg = 1) or (MesgCurr^.TypMsg = 2)
then
begin
private := TRUE;
sep := '*'
end
else sep := ':';
seek(summ_file, MesgCurr^.SummLoc);
read(summ_file, summ_rec);
Writeln(USR, MesgCurr^.MesgNo, sep, ' ', summ_rec.subject);
MesgCurr := MesgCurr^.next;
if user_rec.lines <> 99
then
begin
line_count := succ(line_count);
if line_count mod user_rec.lines = 0
then pause
end
end;
if private
then
begin
Writeln(USR);
Writeln(USR, '"*" marks messages to or from you.')
end
end;
overlay procedure mesg_summary;
{ Message summary }
var
num, first_line, last_line, line_count: integer;
begin
line_count := 0;
num := mesg_start('Start');
MesgCurr := MesgBase;
while (MesgCurr <> nil) and (MesgCurr^.MesgNo < num) do
MesgCurr := MesgCurr^.next;
while (not brk) and (MesgCurr <> nil) do
begin
mesg_header_list(MesgCurr^.SummLoc, first_line, last_line);
MesgCurr := MesgCurr^.next;
if user_rec.lines <> 99
then
begin
line_count := succ(line_count);
if line_count mod (user_rec.lines div 5) = 0
then pause
end
end
end;
overlay procedure mesg_read;
{ Read message }
var
ch: char;
update: boolean;
i, num, first_line, last_line, line_count: integer;
begin
OK := TRUE;
num := mesg_start('Start');
MesgCurr := MesgBase;
while (MesgCurr <> nil) and (MesgCurr^.MesgNo < num) do
MesgCurr := MesgCurr^.next;
while (not brk) and (MesgCurr <> nil) and OK do
begin
if MesgCurr^.MesgNo > user_rec.lasthi
then user_rec.lasthi := MesgCurr^.MesgNo;
mesg_header_list(MesgCurr^.SummLoc, first_line, last_line);
line_count := 4;
i := 1;
seek(mesg_file, first_line);
while (not brk) and (i <= last_line) do
begin
read(mesg_file, mesg_rec);
Writeln(USR, mesg_rec);
i := succ(i);
if user_rec.lines <> 99
then
begin
line_count := succ(line_count);
if line_count mod user_rec.lines = 0
then pause
end
end;
update := (summ_rec.user_to = user_loc) and (summ_rec.status = private);
if update
then summ_rec.status := read;
if user_rec.access >= 250
then
begin
repeat
Writeln(USR);
ch := select('Message command', 'DeleteIndividualMovePublicRead');
case ch of
'D': mesg_delete;
'I': summ_rec.status := private;
'M': summ_rec.area := strint(prompt('Message area', 3, 'E'));
'P': summ_rec.status := public;
'R': summ_rec.status := read;
'?': Writeln(USR, '<D>elete, <I>ndividual (private), <M>ove, <P>ublic, <R>ead')
end
until (not online) or (ch <> '?');
if ch <> 'D'
then MesgCurr := MesgCurr^.next;
update := update or (ch in ['I', 'M', 'P', 'R'])
end
else if (summ_rec.user_from = user_loc) or (summ_rec.user_to = user_loc)
then
begin
Writeln(USR);
if ask('DELETE this message')
then mesg_delete
else
begin
Writeln(USR, 'Message retained.');
MesgCurr := MesgCurr^.next
end
end
else MesgCurr := MesgCurr^.next;
if update
then
begin
seek(summ_file, pred(FilePos(summ_file)));
Write(summ_file, summ_rec)
end;
Writeln(USR);
if MesgCurr <> nil
then if user_rec.lines = 99
then OK := TRUE
else OK := ask('READ next message')
end
end;
overlay procedure mesg_kill;
{ Delete message }
var
num: integer;
begin
num := mesg_start('Message');
MesgCurr := MesgBase;
while (MesgCurr <> nil) and (MesgCurr^.MesgNo < num) do
MesgCurr := MesgCurr^.next;
if MesgCurr^.MesgNo = num
then
begin
seek(summ_file, MesgCurr^.SummLoc);
read(summ_file, summ_rec);
if (user_loc = summ_rec.user_from) or (user_loc = summ_rec.user_to) or
(user_rec.access >= 250)
then mesg_delete
else Writeln(USR, 'Message not to or from you.')
end
else Writeln(USR, 'Message not found.')
end;
overlay procedure mesg_area_change(req: Str10);
{ Change message area }
const
col_width = 12;
var
col_count, col_limit: integer;
this: AreaPtr;
pr: StrPr;
begin
col_limit := max(1, user_rec.columns div col_width);
pr := 'Message area';
if user_rec.help_level > 1
then pr := pr + ' [press "?" for menu]';
if req = ''
then req := prompt(pr, 10, 'ES?');
while req <> '' do
begin
this := AreaBase;
if req = '?'
then
begin
Writeln(USR, 'Available message areas:');
Writeln(USR);
while (not brk) and (this <> nil) do
begin
if user_rec.access >= this^.AreaAccs
then Writeln(USR, pad(this^.AreaName, 14), this^.AreaDesc);
this := this^.next
end;
Writeln(USR);
req := prompt(pr, 10, 'ES?')
end
else if req <> ''
then
begin
while (req <> this^.AreaName) and (this <> nil) do
this := this^.next;
if (req = this^.AreaName) and (user_rec.access >= this^.AreaAccs)
then
begin
AreaSet := this^.Area;
AreaReq := req;
req := '';
mesg_build_index(AreaSet);
mesg_directory
end
else
begin
Writeln(USR, '"', req, '" not found. Available message areas:');
Writeln(USR);
col_count := 0;
this := AreaBase;
while (not brk) and (this <> nil) do
begin
if user_rec.access >= this^.AreaAccs
then
begin
Write(USR, pad(this^.AreaName, col_width));
col_count := succ(col_count);
if 0 = col_count mod col_limit
then Writeln(USR)
end;
this := this^.next
end;
if 0 <> col_count mod col_limit
then Writeln(USR);
Writeln(USR);
req := prompt(pr, 10, 'ES?')
end
end
end
end;
Writeln(USR);