aOberon10.Scn.FntOberon10i.Scn.FntlpVersionElemsAllocBeg#Oberon10.Scn.FntHP LinuxLinuxHP#Oberon10.Scn.FntHPLinux pVersionElemsAllocEnd 6Oberon10b.Scn.FntT  "*8FoldElemsNewHOberon10.Scn.FntN"pVersionElemsAllocBeg#Oberon10.Scn.FntHP LinuxLinuxHP#Oberon10.Scn.FntyyUnix.LockF(mail.fd, 0, 0); (* Unlock File *) Unix.LockF(mail.fd, 1, 0); (* Lock all file and sleep if already locked *)Linux Oberon10i.Scn.Fnt/pVersionElemsAllocEnd%op#Oberon10.Scn.FntHP LinuxLinuxHP#Oberon10.Scn.Fnt,,Unix.LockF(mail.fd, 0, 0); (* Unlock File *)Linux pz VAR mail: Files.File; actualSize: LONGINT; BEGIN mail := Files.Old(MAIL); Unix.LockF(mail.fd, 0); (* Unlock File *) Unix.LockF(mail.fd, 1); (* Lock all file and sleep if already locked *) actualSize := Files.Length(mail); Unix.LockF(mail.fd, 0); (* Unlock File *) IF actualSize # prevSize THEN prevSize := Files.Length(mail); RETURN TRUE ELSE RETURN FALSE END; END IsNewMail; 88#Oberon10.Scn.Fnt VAR W: Texts.Writer; BEGIN Texts.OpenWriter(W); Texts.WriteLn(W); Texts.WriteString(W, "New mail"); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); X11.Bell (X11.display, 50) END DefaultBell; 8  18#Oberon10.Scn.Fnt VAR m: Modules.Module; BEGIN m := Modules.ThisMod (mod); IF m # NIL THEN bellCmd := Modules.ThisCommand (m, proc) ELSE bellCmd := DefaultBell END; END SetBellCmd; 8j8#Oberon10.Scn.Fnttt BEGIN IF IsNewMail() THEN bellCmd END; Task.time := Input.Time() + pollPeriod * Input.TimeUnit END CheckMail; 8D/8#Oberon10.Scn.Fnt VAR i: INTEGER; BEGIN Texts.Read(R, nextch); i := 0; WHILE (i < 5) & (nextch >= " ") DO word[i] := nextch; INC(i); Texts.Read(R, nextch) END ; word[i] := 0X END GetWord; 8d8#Oberon10.Scn.Fnt## VAR i: INTEGER; ch: CHAR; tag: ARRAY 32 OF CHAR; R: Texts.Reader; BEGIN Texts.OpenReader(R, t, pos); LOOP i := 0; REPEAT Texts.Read(R, ch); tag[i] := ch; INC(i) UNTIL (ch <= " ") OR (i = 31); tag[i - 1] := 0X; IF tag = entry THEN i := - 1; REPEAT Texts.Read(R, ch); INC(i); line[i] := ch UNTIL ch <= CR; IF entry = "From" THEN i := 0; WHILE line[i] > " " DO INC(i) END END; line[i] := 0X; EXIT ELSIF R.eot OR (ch = CR) THEN line[0] := 0X; EXIT END ; REPEAT Texts.Read(R, ch) UNTIL ch <= CR END END GetHeader; 888#Oberon10.Scn.Fnt VAR i: INTEGER; word: ARRAY 6 OF CHAR; BEGIN REPEAT WHILE (nextch # CR) & (nextch # 0X) DO Texts.Read(R, nextch) END ; mail.len := Texts.Pos(R) - mail.start; GetWord(R, word) UNTIL (word = "From ") OR R.eot END SkipMail; 8c8#Oberon10.Scn.FntFF VAR W: Texts.Writer; R, R1: Texts.Reader; mail: Mail; nofmails: LONGINT; word: ARRAY 6 OF CHAR; line: ARRAY 256 OF CHAR; BEGIN Texts.OpenWriter(W); nofmails := 0; Texts.OpenReader(R, T, 0); GetWord(R, word); MB := TextFrames.Text(""); WHILE ~ R.eot DO NEW(mail); mail.start := Texts.Pos(R) - 6; mail.del := FALSE; mail.nr := nofmails; Texts.WriteInt(W, nofmails, 2); IF mail.start < newMailPos THEN Texts.WriteString(W, " ") ELSE Texts.WriteString(W, " + ") END ; GetHeader(T, mail.start, "From:", line); IF line = "" THEN GetHeader(T, mail.start, "From", line) END ; Texts.WriteString(W, line); Texts.WriteString(W, " "); GetHeader(T, mail.start, "Subject:", line); Texts.WriteString(W, line); SkipMail(R, mail); mail^.next := mails^.next; mails^.next := mail; IF mail.len > 16 * 1024 THEN W.col := 1 ELSIF mail.len > 8 * 1024 THEN W.col := 4 ELSIF mail.len > 4 * 1024 THEN W.col := 5 ELSE W.col := 15 END; Texts.WriteInt(W, mail.len, 8); Texts.WriteLn(W); W.col := 15; Texts.Insert(MB, 0, W.buf); INC(nofmails) END END MailBoxText; 88TOberon10.Scn.Fnt<pVersionElemsAllocBeg#Oberon10.Scn.FntHP LinuxLinuxHP#Oberon10.Scn.Fntvar: Unix.EnvVar;Linux Oberon10i.Scn.Fnt6pVersionElemsAllocEndp#Oberon10.Scn.FntHP LinuxLinuxHP#Oberon10.Scn.FntvarName := "MAIL"; var := Unix.Getenv(SYSTEM.ADR(varName), LEN(varName)); IF var # NIL THEN COPY(var.name, MAIL) ELSE MAIL := mailDefault; i := 16; j := 0; REPEAT ch := Oberon.User[j]; MAIL[i] := ch; INC(i); INC(j) UNTIL ch = 0X END ; varName := "MBOX"; var := Unix.Getenv(SYSTEM.ADR(varName), LEN(varName)); IF var # NIL THEN COPY(var.name, MBOX) ELSE varName := "HOME"; var := Unix.Getenv(SYSTEM.ADR(varName), LEN(varName)); IF var # NIL THEN COPY(var.name, MBOX) ELSE MBOX[0] := "."; MBOX[1] := 0X END ; i := 0; WHILE MBOX[i] # 0X DO INC(i) END ; MBOX[i] := "/"; MBOX[i+1] := "m"; MBOX[i+2] := "b"; MBOX[i+3] := "o"; MBOX[i+4] := "x"; MBOX[i+5] := 0X END Linux 2p  VAR i, j: INTEGER; ch: CHAR; varName: ARRAY 64 OF CHAR; (* The Linux version of this procedure is simplified*) BEGIN MAIL := mailDefault; i := 16; j := 0; REPEAT ch := Oberon.User[j]; MAIL[i] := ch; INC(i); INC(j) UNTIL ch = 0X; MBOX[0] := "."; MBOX[1] := 0X; i := 0; WHILE MBOX[i] # 0X DO INC(i) END ; MBOX[i] := "/"; MBOX[i + 1] := "m"; MBOX[i + 2] := "b"; MBOX[i + 3] := "o"; MBOX[i + 4] := "x"; MBOX[i + 5] := 0X  END Init; 8N  8VOberon10.Scn.FntOberon10i.Scn.Fnt&v"pVersionElemsAllocBeg#Oberon10.Scn.FntHP LinuxLinuxHP#Oberon10.Scn.FntyyUnix.LockF(mail.fd, 0, 0); (* Unlock File *) Unix.LockF(mail.fd, 1, 0); (* Lock all file and sleep if already locked *)Linux /pVersionElemsAllocEndop#Oberon10.Scn.FntHP LinuxLinuxHP#Oberon10.Scn.Fnt,,Unix.LockF(mail.fd, 0, 0); (* Unlock File *)Linux p VAR X, Y, res: INTEGER; ch: CHAR; V: MenuViewers.Viewer; mail, mbox: Files.File; mailR, mboxR: Files.Rider; mailfile: ARRAY 64 OF CHAR; F: Frame; newMailPos: LONGINT; BEGIN In.Open; In.Name(mailfile); newMailPos := MAX(LONGINT); IF ~In.Done THEN mail := Files.Old(MAIL); mbox := Files.Old(MBOX); IF mbox = NIL THEN mbox := Files.New(MBOX); Files.Register(mbox) END ; IF (mail # NIL) & (Files.Length(mail) # 0) THEN (*append mail to mbox and purge mail*) newMailPos := Files.Length(mbox); Files.Set(mboxR, mbox, Files.Length(mbox)); Files.Set(mailR, mail, 0); Unix.LockF(mail.fd, 0); (* Unlock File *) Unix.LockF(mail.fd, 1); (* Lock all file and sleep if already locked *) Files.Read(mailR, ch); WHILE ~mailR.eof DO Files.Write(mboxR, ch); Files.Read(mailR, ch) END ; Files.Close(mbox); Files.Purge(mail); Files.Set(mailR, mail, 0); Unix.LockF(mail.fd, 0); (* Unlock File *) prevSize := Files.Length(mail) END ; COPY(MBOX, mailfile) END ; NEW(F); F.mailText := TextFrames.Text(mailfile); IF F.mailText # NIL THEN F.mailFileLen := F.mailText.len; NEW(F.mails); MailBoxText(F.mailText, newMailPos, F.text, F.mails); TextFrames.Open(F, F.text, 0); Oberon.AllocateSystemViewer(Oberon.Mouse.X, X, Y); V := MenuViewers.New( TextFrames.NewMenu(mailfile, "System.Close Mailer.Show Mailer.Delete Mailer.Store "), F, TextFrames.menuH, X, Y) END END Mailbox; 858#Oberon10.Scn.Fnt VAR menu: TextFrames.Frame; W: Texts.Writer; BEGIN menu := TextFrames.NewMenu("", showMenu); Texts.OpenWriter(W); Texts.WriteString(W, "Message"); Texts.WriteInt(W, i, 0); Texts.WriteString(W, ".Text"); Texts.Insert(menu.text, 0, W.buf); RETURN menu END ShowMenu; 8 8#Oberon10.Scn.Fnt VAR X, Y: INTEGER; mail: Mail; S: Texts.Scanner; F: Display.Frame; B: Texts.Buffer; V: MenuViewers.Viewer; T: Texts.Text; BEGIN F := Oberon.Par.vwr.dsc.next; IF (F IS Frame) & (F(Frame).hasSel) THEN WITH F: Frame DO Oberon.AllocateUserViewer(Oberon.Mouse.X, X, Y); Texts.OpenScanner(S, F.text, F.selbeg.org); Texts.Scan(S); IF S.class = Texts.Int THEN mail := F.mails.next; WHILE (mail # NIL) & (mail.nr # S.i) DO mail := mail.next END ; IF mail # NIL THEN T := TextFrames.Text(""); NEW(B); Texts.OpenBuf(B); Texts.Save(F.mailText, mail.start, mail.start + mail.len, B); Texts.Append(T, B); V := MenuViewers.New(ShowMenu(S.i), TextFrames.NewText(T, 0), TextFrames.menuH, X, Y) END END END END END Show; 8 8#Oberon10.Scn.Fnt VAR mail, m: Mail; S: Texts.Scanner; F: Display.Frame; n: INTEGER; R: Texts.Reader; ch: CHAR; T: Texts.Text; BEGIN F := Oberon.Par.vwr.dsc.next; IF (F IS Frame) & (F(Frame).hasSel) THEN WITH F: Frame DO Texts.OpenScanner(S, F.text, F.selbeg.org); Texts.Scan(S); IF S.class = Texts.Int THEN Texts.OpenReader(R, F.text, F.selbeg.pos); n := 1; Texts.Read(R, ch); WHILE Texts.Pos(R) < F.selend.pos - 1 DO IF ch = 0DX THEN INC(n) END ; Texts.Read(R, ch) END ; mail := F.mails.next; WHILE (mail # NIL) & (mail.nr # S.i) DO mail := mail.next END ; IF mail # NIL THEN WHILE (mail # NIL) & (n > 0) DO m := F.mails; Texts.Delete(F.mailText, mail.start, mail.start + mail.len); WHILE m.next # mail DO m := m.next; DEC(m.start, mail.len) END ; m.next := mail.next; mail := mail.next; DEC(n) END ; WHILE (ch >= " ") OR (ch = 09X) DO Texts.Read(R, ch) END ; Texts.Delete(F.text, F.selbeg.org, Texts.Pos(R)) END END END END END Delete; 8 8Oberon10.Scn.FntnpVersionElemsAllocBeg#Oberon10.Scn.FntHP LinuxLinuxHP#Oberon10.Scn.Fnt--Unix.Chmod(SYSTEM.ADR(S.s), mboxPermissions);Linux DpVersionElemsAllocEnd VAR mail, m: Mail; F: Display.Frame; S: Texts.Scanner; R: Texts.Reader; ch: CHAR; mbox: Files.File; mboxR: Files.Rider; W: Texts.Writer; T: Texts.Text; l: LONGINT; BEGIN F := Oberon.Par.vwr.dsc; IF (F = Oberon.Par.frame) & (F.next IS Frame) THEN Texts.OpenScanner(S, Oberon.Par.text, 0); Texts.Scan(S); mbox := Files.New(S.s); Files.Set(mboxR, mbox, 0); Texts.OpenWriter(W); Texts.WriteString(W, "Mailer.Store "); Texts.WriteString(W, S.s); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); Texts.OpenReader(R, F.next(Frame).mailText, 0); Texts.Read(R, ch); WHILE ~R.eot DO IF ch = CR THEN ch := LF END ; Files.Write(mboxR, ch); Texts.Read(R, ch) END ; Files.Register(mbox); l := Unix.Chmod(SYSTEM.ADR(S.s), SYSTEM.VAL(SET, mboxPermissions));  IF F IS TextFrames.Frame THEN T := F(TextFrames.Frame).text; Texts.OpenReader(R, T, T.len - 1); Texts.Read(R, ch); IF ch = "!" THEN Texts.Delete(T, T.len - 1, T.len) END END END END Store; 8 G8QOberon10.Scn.FntOberon10i.Scn.FntA+i VAR V: Display.Frame; temp: Files.File; S: Texts.Scanner; R: Texts.Reader; mR: Files.Rider; ch: CHAR; res: INTEGER; W: Texts.Writer; cmdStr: ARRAY 256 OF CHAR; BEGIN IF Oberon.Par.frame = Oberon.Par.vwr.dsc THEN V := Oberon.Par.vwr ELSE V := Oberon.MarkedViewer() END ; IF (V # NIL) & (V IS MenuViewers.Viewer) & (V.dsc.next IS TextFrames.Frame) THEN Texts.OpenWriter(W); Texts.OpenScanner(S, V.dsc(TextFrames.Frame).text, 0); Texts.Scan(S); Texts.OpenReader(R, V.dsc.next(TextFrames.Frame).text, 0); temp := Files.New("/tmp/Mailer.Send"); Files.Set(mR, temp, 0); Texts.Read(R, ch); WHILE ~R.eot DO IF ch = CR THEN ch := LF END ; Files.Write(mR, isoChar[ORD(ch)]); Texts.Read(R, ch) END ; Texts.WriteString(W, S.s); Texts.WriteString(W, " mailing"); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); Files.Register(temp); cmdStr := "(/usr/lib/sendmail -oi -t < /tmp/Mailer.Send; rm /tmp/Mailer.Send) &"; Unix.System (SYSTEM.ADR(cmdStr), LEN(cmdStr)); (* Unix.System("/usr/lib/sendmail -oi -t < /tmp/Mailer.Send"); *) (* Files.Delete("/tmp/Mailer.Send", res) *) END END Send; 8 R8#Oberon10.Scn.Fnt VAR V: Display.Frame; temp: Files.File; S: Texts.Scanner; R: Texts.Reader; mR: Files.Rider; ch: CHAR; res: INTEGER; W: Texts.Writer; cmdStr: ARRAY 256 OF CHAR; BEGIN V := Oberon.MarkedViewer(); IF (V # NIL) & (V.dsc.next IS TextFrames.Frame) THEN Texts.OpenWriter(W); Texts.OpenScanner(S, V.dsc(TextFrames.Frame).text, 0); Texts.Scan(S); Texts.OpenReader(R, V.dsc.next(TextFrames.Frame).text, 0); temp := Files.New("/tmp/Mailer.Post"); Files.Set(mR, temp, 0); Texts.Read(R, ch); WHILE ~R.eot DO IF ch = CR THEN ch := LF END ; Files.Write(mR, ch); Texts.Read(R, ch) END ; Texts.WriteString(W, S.s); Texts.WriteString(W, " posting"); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); Files.Register(temp); cmdStr := "/usr/lib/news/inews -h < /tmp/Mailer.Post"; Unix.System (SYSTEM.ADR(cmdStr), LEN(cmdStr)); Files.Delete("/tmp/Mailer.Post", res) END END Post; 8P8#Oberon10.Scn.FntBB VAR W: Texts.Writer; R: Texts.Reader; ch: CHAR; BEGIN Texts.OpenWriter(W); REPEAT Texts.WriteString(W, qs); Texts.Write(W, " "); Texts.Insert(text, beg, W.buf); INC(end, 2); Texts.OpenReader(R, text, beg); REPEAT Texts.Read(R, ch); INC(beg) UNTIL (ch = CR) OR (beg >= end) UNTIL beg >= end END QuoteText; 8 8#Oberon10.Scn.Fnt VAR text: Texts.Text; qs: ARRAY 32 OF CHAR; beg, end, time: LONGINT; BEGIN Oberon.GetSelection(text, beg, end, time); In.Open; In.String(qs); IF ~In.Done THEN qs := ">" END; IF time >= 0 THEN QuoteText(text, beg, end, qs) END END Quote; 8CH8#Oberon10.Scn.Fnt VAR menu: TextFrames.Frame; W: Texts.Writer; S: Texts.Scanner; BEGIN menu := TextFrames.NewMenu("", replyMenu); Texts.OpenScanner(S, parFrame(TextFrames.Frame).text, 0); Texts.Scan(S); Texts.OpenWriter(W); Texts.WriteString(W, "Reply."); IF S.class = Texts.Name THEN Texts.WriteString(W, S.s) ELSE Texts.WriteString(W, "Text") END ; Texts.Insert(menu.text, 0, W.buf); RETURN menu END ReplyMenu; 8 8#Oberon10.Scn.Fnt VAR X, Y: INTEGER; ch: CHAR; beg: LONGINT; T: Texts.Text; W: Texts.Writer; V: MenuViewers.Viewer; F: TextFrames.Frame; B: Texts.Buffer; line: ARRAY 256 OF CHAR; BEGIN Oberon.AllocateUserViewer(Oberon.Mouse.X, X, Y); IF Oberon.Par.vwr.dsc = Oberon.Par.frame THEN F := Oberon.Par.frame.next(TextFrames.Frame); Texts.OpenWriter(W); GetHeader(F.text, 0, "Reply-To:", line); IF line = "" THEN GetHeader(F.text, 0, "From:", line) END ; IF line = "" THEN GetHeader(F.text, 0, "From", line) END ; Texts.WriteString(W, "To: "); Texts.WriteString(W, line); Texts.WriteLn(W); GetHeader(F.text, 0, "Subject:", line); Texts.WriteString(W, "Subject: Re: "); Texts.WriteString(W, line); Texts.WriteLn(W); Texts.WriteLn(W); T := TextFrames.Text(""); Texts.Append(T, W.buf); IF F.hasSel THEN beg := T.len; NEW(B); Texts.OpenBuf(B); Texts.Save(F.text, F.selbeg.pos, F.selend.pos, B); Texts.Append(T, B); QuoteText(T, beg, T.len, ">"); Texts.WriteLn(W); Texts.Append(T, W.buf) END ; V := MenuViewers.New(ReplyMenu(Oberon.Par.frame), TextFrames.NewText(T, 0), TextFrames.menuH, X, Y); Oberon.PassFocus(V); TextFrames.SetCaret(V.dsc.next(TextFrames.Frame), T.len) END END Reply; 8 8#Oberon10.Scn.Fnt: : VAR f: Files.File; V: Display.Frame; R0: Texts.Reader; R1: Files.Rider; S: Texts.Scanner; ch: CHAR; to: ARRAY 64 OF CHAR; W: Texts.Writer; buffer: ARRAY 1024 OF CHAR; i: LONGINT; from, subject, inHeader: BOOLEAN; viewerName: ARRAY 128 OF CHAR; PROCEDURE Prefix (str, pattern: ARRAY OF CHAR): BOOLEAN; VAR i: LONGINT; BEGIN i := 0; WHILE (pattern[i] # 0X) & (str[i] = pattern[i]) DO INC(i) END; RETURN pattern[i] = 0X END Prefix; PROCEDURE Write (buf: ARRAY OF CHAR); VAR i: LONGINT; BEGIN i := 0; WHILE buf[i] # 0X DO Files.Write(R1, buf[i]); INC(i) END END Write; PROCEDURE CheckFrom; VAR i: LONGINT; BEGIN IF Prefix (buffer, "From") THEN Write ("From "); i := 4; WHILE (buffer[i] # 0X) & (buffer[i] = " ") DO INC(i) END; WHILE buffer[i] # 0X DO Files.Write(R1, buffer[i]); INC(i) END; buffer[0] := 0X ELSE Write ("From "); Write (viewerName); Write (LF) END; from := TRUE END CheckFrom; PROCEDURE CheckSubject; VAR i: LONGINT; BEGIN IF Prefix (buffer, "Re:") THEN Write ("Subject:"); i := 3; WHILE buffer[i] # 0X DO Files.Write(R1, buffer[i]); INC(i) END; buffer[0] := 0X; subject := TRUE ELSIF Prefix (buffer, "Subject:") THEN subject := TRUE END; END CheckSubject; BEGIN In.Open; In.Name(to); V := Oberon.MarkedViewer(); IF In.Done & (V IS MenuViewers.Viewer) & (V.dsc.next IS TextFrames.Frame) THEN Texts.OpenWriter(W); Texts.OpenScanner(S, V.dsc(TextFrames.Frame).text, 0); Texts.Scan (S); IF (S.class = Texts.Name) OR (S.class = Texts.String) THEN COPY (S.s, viewerName) ELSE viewerName := "*" END; Texts.WriteString(W, " appending "); Texts.WriteString(W, viewerName); Texts.WriteString(W, " to "); Texts.WriteString(W, to); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); f := Files.Old(to); IF f = NIL THEN f := Files.New(to) END; Files.Set(R1, f, Files.Length(f)); Texts.OpenReader(R0, V.dsc.next(TextFrames.Frame).text, 0); Texts.Read(R0, ch); from := FALSE; subject := FALSE; WHILE ~R0.eot DO i := 0; WHILE (~R0.eot) & (ch # LF) & (ch # CR) DO buffer[i] := ch; Texts.Read(R0, ch); INC(i) END; buffer[i] := LF; buffer[i + 1] := 0X; IF ~R0.eot THEN Texts.Read(R0, ch) END; IF inHeader THEN IF ~from THEN CheckFrom END; IF ~subject THEN CheckSubject END END; Write(buffer) END; Files.Write(R1, LF); Files.Register(f) END END Append; 8 n8#Oberon10.Scn.Fntpp VAR V: Display.Frame; T: Texts.Text; BEGIN IF Oberon.Par.frame = Oberon.Par.vwr.dsc THEN V := Oberon.Par.vwr ELSE V := Oberon.MarkedViewer() END ; IF (V # NIL) & (V IS MenuViewers.Viewer) & (V.dsc.next IS TextFrames.Frame) THEN T := V.dsc.next(TextFrames.Frame).text; Texts.ChangeLooks(T, 0, T.len, {0}, Fonts.This("Courier10.Scn.Fnt"), 0, 0) END END Mono; 8 p8#Oberon10.Scn.Fntnn VAR V: Display.Frame; T: Texts.Text; BEGIN IF Oberon.Par.frame = Oberon.Par.vwr.dsc THEN V := Oberon.Par.vwr ELSE V := Oberon.MarkedViewer() END ; IF (V # NIL) & (V IS MenuViewers.Viewer) & (V.dsc.next IS TextFrames.Frame) THEN T := V.dsc.next(TextFrames.Frame).text; Texts.ChangeLooks(T, 0, T.len, {0}, Fonts.This("Syntax14.Scn.Iso"), 0, 0) END END Iso; 8  o8COberon10.Scn.FntOberon10i.Scn.Fnt AO (* by R.G. *) CONST default = 80; VAR lim, beg, end, pos: LONGINT; ch: CHAR; S: Texts.Scanner; V: Display.Frame; T: Texts.Text; R: Texts.Reader; W: Texts.Writer; BEGIN Texts.OpenWriter(W); Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S); IF (S.line = 0) & (S.class = Texts.Int) & (S.i > 1) THEN lim := S.i; Texts.Scan(S) ELSE lim := default END; IF (S.line = 0) & (S.class = Texts.Char) & (S.c = "*") THEN V := Oberon.MarkedViewer(); IF (V # NIL) & (V.dsc # NIL) & (V.dsc.next # NIL) & (V.dsc.next IS TextFrames.Frame) THEN T := V.dsc.next(TextFrames.Frame).text; pos := 0; beg := 0; end := lim - 1; Texts.OpenReader(R, T, 0); LOOP Texts.Read(R, ch); INC(pos); IF R.eot THEN EXIT ELSIF ch = 0DX THEN beg := pos; end := beg + lim - 1 ELSIF pos - beg = lim THEN Texts.Write(W, 0DX); Texts.Insert(T, end, W.buf); pos := end; Texts.OpenReader(R, T, pos) ELSIF (ch <= " ") OR (ch = "-") THEN end := pos ELSIF (80X <= ch) & (ch <= 85X) THEN CASE ch OF | 80X: ch := "A" | 81X: ch := "O" | 82X: ch := "U" | 83X: ch := "a" | 84X: ch := "o" | 85X: ch := "u" END; DEC(pos); Texts.Delete(T, pos, pos + 1); Texts.Write(W, ch); Texts.Write(W, "e"); Texts.Insert(T, pos, W.buf); Texts.OpenReader(R, T, pos) END END END END END CutLines; 8 &8#Oberon10.Scn.Fnt VAR cmd: ARRAY 128 OF CHAR; i, j: INTEGER; bellMod, bellProc: ARRAY 64 OF CHAR; BEGIN In.Open; In.Name (cmd); IF In.Done THEN i := 0; WHILE (cmd[i] # 0X) & (cmd[i] # ".") DO bellMod[i] := cmd[i]; INC(i) END; bellMod[i] := 0X; IF cmd[i] = "." THEN INC(i); j := 0; WHILE cmd[i] # 0X DO bellProc[j] := cmd[i]; INC(i); INC(j) END; bellProc[j] := 0X; SetBellCmd (bellMod, bellProc) END; END END SetBell; 8 8#Oberon10.Scn.Fnt00 BEGIN Oberon.Install(Task) END InstallPoller; 8  8#Oberon10.Scn.Fnt.. BEGIN Oberon.Remove(Task) END RemovePoller; 8 8#Oberon10.Scn.FntPP CONST bufSize = 128; VAR v: Viewers.Viewer; f: Display.Frame; t: Texts.Text; r: Texts.Reader; w: Texts.Writer; pos, bPos, pos0, i, len: LONGINT; ch: CHAR; buffer, res: ARRAY bufSize OF CHAR; col, voff: SHORTINT; fnt: Fonts.Font; PROCEDURE Search (VAR alias, name: ARRAY OF CHAR; VAR len: LONGINT); VAR T: Texts.Text; S: Texts.Scanner; id: ARRAY 64 OF CHAR; BEGIN NEW(T); Texts.Open(T, "Alias.Text"); len := 0; IF T # NIL THEN Texts.OpenScanner(S, T, 0); LOOP Texts.Scan(S); IF S.class # Texts.Name THEN EXIT END; COPY (S.s, id); Texts.Scan(S); IF S.class # Texts.String THEN EXIT END; IF id = alias THEN COPY(S.s, name); WHILE name[len] # 0X DO INC(len) END; EXIT END; END END; END Search; BEGIN Texts.OpenWriter (w); v := Oberon.FocusViewer; IF v IS MenuViewers.Viewer THEN f := v.dsc.next; IF f IS TextFrames.Frame THEN WITH f: TextFrames.Frame DO IF f.hasCar THEN t := f.text; pos := f.carloc.pos; bPos := bufSize; i := pos - 1; LOOP IF i < 0 THEN EXIT END; Texts.OpenReader (r, t, i); Texts.Read(r, ch); col := r.col; fnt := r.fnt; voff := r.voff; IF ch <= "0" THEN EXIT END; DEC(bPos); buffer[bPos] := ch; DEC(i) END; pos0 := i + 1; i := 0; WHILE bPos < bufSize DO buffer[i] := buffer[bPos]; INC(bPos); INC(i) END; buffer[i] := 0X; Search (buffer, res, len); IF len > 0 THEN Texts.WriteString (w, res); Texts.Delete (t, pos0, pos); Texts.Insert (t, pos0, w.buf); TextFrames.SetCaret (f, pos0 + len) END; END END; END END; END Alias; 88#Oberon10.Scn.Fnt<< VAR i: INTEGER; BEGIN i := 0; WHILE i < 256 DO oberonChar[i] := CHR(i); INC(i) END; oberonChar[196] := CHR(128); oberonChar[214] := CHR(129); oberonChar[220] := CHR(130); oberonChar[228] := CHR(131); oberonChar[246] := CHR(132); oberonChar[252] := CHR(133); oberonChar[226] := CHR(134); oberonChar[234] := CHR(135); oberonChar[238] := CHR(136); oberonChar[244] := CHR(137); oberonChar[251] := CHR(138); oberonChar[224] := CHR(139); oberonChar[232] := CHR(140); oberonChar[236] := CHR(141); oberonChar[242] := CHR(142); oberonChar[249] := CHR(143); oberonChar[233] := CHR(144); oberonChar[235] := CHR(145); oberonChar[239] := CHR(146); oberonChar[231] := CHR(147); oberonChar[225] := CHR(148); oberonChar[241] := CHR(149); i := 0; WHILE i < 256 DO isoChar[ORD(oberonChar[i])] := CHR(i); INC(i) END END InitCharTable; 858#Oberon10.Scn.Fnt InitCharTable; prevSize := 0; bellCmd := DefaultBell; pollPeriod := defaultPollPeriod; NEW(Task); Task.safe := TRUE; Task.time := 0; Task.handle := CheckMail; Init8  MODULE Mailer; (* Copyright (c) Joseph Templ, 1990-96 / jt 22.04.93 *) (* Modifications for Linux by RLI; Select Version: Linux *) IMPORT SYSTEM, Modules, Unix, X11, Kernel, Input, Oberon, TextFrames, Viewers, Texts, MenuViewers, Display, Files, Fonts, In; CONST CR = 0DX; LF = 0AX; defaultPollPeriod = 15; (* sec *) mboxPermissions = 0180H; mailDefault = "/usr/spool/mail/"; showMenu = "System.Close System.Copy System.Grow Edit.Search Mailer.Reply Mailer.Mono Edit.Store "; replyMenu = "System.Close System.Copy System.Grow Edit.Search !Mailer.Send Mailer.Mono Edit.Store "; TYPE Mail = POINTER TO MailDesc; MailDesc = RECORD next: Mail; start, len, nr: LONGINT; del: BOOLEAN END; Frame = POINTER TO FrameDesc; FrameDesc = RECORD (TextFrames.FrameDesc) mailText: Texts.Text; mailFileName: ARRAY 110 OF CHAR; mailFileLen: LONGINT; mails: Mail END ; VAR MAIL*, MBOX*: ARRAY 110 OF CHAR; (* environment variables *) bellCmd: Modules.Command; Task: Oberon.Task; nextch: CHAR; prevSize: LONGINT; pollPeriod*: LONGINT; isoChar: ARRAY 256 OF CHAR; oberonChar: ARRAY 256 OF CHAR; PROCEDURE IsNewMail (): BOOLEAN;  PROCEDURE DefaultBell;  PROCEDURE SetBellCmd* (mod, proc: ARRAY OF CHAR);  PROCEDURE CheckMail;  PROCEDURE GetWord (VAR R: Texts.Reader; VAR word: ARRAY OF CHAR);  PROCEDURE GetHeader (t: Texts.Text; pos: LONGINT; entry: ARRAY OF CHAR; VAR line: ARRAY OF CHAR);  PROCEDURE SkipMail (VAR R: Texts.Reader; mail: Mail);  PROCEDURE MailBoxText (T: Texts.Text; newMailPos: LONGINT; VAR MB: Texts.Text; VAR mails: Mail);  PROCEDURE Init;  (* ------------------------------- commands ------------------------------- *) PROCEDURE Mailbox*;  PROCEDURE ShowMenu (i: LONGINT): TextFrames.Frame;  PROCEDURE Show*;  PROCEDURE Delete*;  PROCEDURE Store*;  PROCEDURE Send*;  PROCEDURE Post*;  PROCEDURE QuoteText (text: Texts.Text; beg, end: LONGINT; qs: ARRAY OF CHAR);  PROCEDURE Quote*;  PROCEDURE ReplyMenu (parFrame: Display.Frame): TextFrames.Frame;  PROCEDURE Reply*;  PROCEDURE Append*;  PROCEDURE Mono*;  PROCEDURE Iso*;  PROCEDURE CutLines*;  PROCEDURE SetBell*;  PROCEDURE InstallPoller*;  PROCEDURE RemovePoller*;  PROCEDURE Alias*;  PROCEDURE InitCharTable;  BEGIN END Mailer.