Compare commits

...

4 Commits

Author SHA1 Message Date
d921a2b144 Escape LF in board file, refuse to store or print control chars 2024-10-11 16:54:56 -04:00
31d7c63114 Add Makefile 2024-10-11 16:26:59 -04:00
e575f1b3d3 Add .gitignore 2024-10-11 16:26:52 -04:00
e55136e433 More man page tweaks 2024-10-11 16:26:30 -04:00
4 changed files with 71 additions and 11 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/bulb

30
Makefile Normal file
View File

@@ -0,0 +1,30 @@
.POSIX:
.SUFFIXES:
HARE=hare
HAREFLAGS=
DESTDIR=
PREFIX=/usr/local
BINDIR=$(PREFIX)/bin
MANDIR=$(PREFIX)/share/man
all: bulb
bulb:
$(HARE) build $(HAREFLAGS) -o $@ cmd/$@/
check:
$(HARE) test $(HAREFLAGS)
clean:
rm -f bulb
install:
mkdir -p $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man1
install -Dm755 bulb $(DESTDIR)$(BINDIR)/bulb
install -Dm755 doc/*.1 $(DESTDIR)$(MANDIR)/man1
uninstall:
rm -f $(DESTDIR)$(BINDIR)/bulb
.PHONY: all check clean install uninstall

View File

@@ -82,7 +82,7 @@ that the receiving user(s) be both logged in and monitoring their terminal for
any messages to ever get through. The any messages to ever get through. The
.BR bulb (1) .BR bulb (1)
command was written to support asynchronous, persistent conversations between command was written to support asynchronous, persistent conversations between
users of the same system. It is also possible to create bulletins, MOTDs, etc. users of the same system.
.\" .\"
.SH AUTHOR .SH AUTHOR

View File

@@ -1,3 +1,4 @@
use ascii;
use bufio; use bufio;
use fs; use fs;
use fmt; use fmt;
@@ -40,8 +41,37 @@ export fn read(output: io::handle, board: str, number: int) (void | error) = {
// we add 1 to account for the blank line that will always be at the // we add 1 to account for the blank line that will always be at the
// bottom // bottom
seek_to_nth_last_line(file, number + 1)?; seek_to_nth_last_line(file, number + 1)?;
// TODO don't copy control characters!
io::copy(output, file)?; static let output_wbuf: [os::BUFSZ]u8 = [0...];
let output = bufio::init(output, [], output_wbuf);
let file = bufio::newscanner(file);
defer bufio::finish(&file);
let saw_escape = false;
for (true) {
let byte = match (bufio::scan_byte(&file)?) {
case let byte: u8 => yield byte;
case io::EOF => break;
};
if (byte == '\x1b') {
saw_escape = true;
} else {
if (byte == '\n') {
if (saw_escape) {
fmt::fprint(&output, "\n ")?;
} else {
fmt::fprint(&output, "\n")?;
};
} else if (!ascii::iscntrl(byte: rune)) {
let fake_buffer: [1]u8 = [byte];
io::write(&output, fake_buffer)?;
};
saw_escape = false;
};
};
bufio::flush(&output)?;
}; };
export fn post(input: io::handle, board: str, user_name: (str | void)) (void | error) = { export fn post(input: io::handle, board: str, user_name: (str | void)) (void | error) = {
@@ -57,26 +87,25 @@ export fn post(input: io::handle, board: str, user_name: (str | void)) (void | e
static let file_wbuf: [os::BUFSZ]u8 = [0...]; static let file_wbuf: [os::BUFSZ]u8 = [0...];
let file = bufio::init(file, [], file_wbuf); let file = bufio::init(file, [], file_wbuf);
let scanner = bufio::newscanner(input); let input = bufio::newscanner(input);
defer bufio::finish(&scanner); defer bufio::finish(&input);
let saw_break = false; let saw_break = false;
fmt::fprintf(&file, "{}: ", user)?; fmt::fprintf(&file, "{}: ", user)?;
for (true) { for (true) {
let byte = match (bufio::scan_byte(&scanner)?) { let byte = match (bufio::scan_byte(&input)?) {
case let byte: u8 => yield byte; case let byte: u8 => yield byte;
case io::EOF => break; case io::EOF => break;
}; };
if (saw_break) { if (saw_break) {
fmt::fprint(&file, "\n ")?; fmt::fprint(&file, "\x1b\n")?;
saw_break = false; saw_break = false;
}; };
switch (byte) { if (byte == '\n') {
case '\n' =>
saw_break = true; saw_break = true;
case => } else if (!ascii::iscntrl(byte: rune)) {
let fake_buffer: [1]u8 = [byte]; let fake_buffer: [1]u8 = [byte];
io::write(&file, fake_buffer)?; io::write(&file, fake_buffer)?;
}; };