:; fortune
You can't build a bomb at 300 baud.
:; ls -l
--rw-rw-r-- M 117298 a sys 554 Jun 6 2022 about
d-rwxrwxr-x M 117298 a sys 0 Jul 5 2021 banner
d-rwxrwxr-x M 117298 a sys 0 Mar 5 10:21 daily
d-rwxrwxr-x M 117298 a sys 0 Dec 8 2021 edterm
d-rwxrwxr-x M 117298 a sys 0 Jun 8 2021 finger
d-rwxrwxr-x M 117298 a sys 0 May 30 2022 fingers
d-rwxrwxr-x M 117298 a sys 0 Mar 2 2021 mtte
d-rwxrwxr-x M 117298 a sys 0 Feb 14 2021 tw
d-rwxrwxr-x M 117298 a sys 0 Nov 14 2022 wikifs
d-rwxrwxr-x M 117298 a sys 0 Nov 7 2021 zine
:; cat about
: txtpunk;
Text is a self-describing interface.
ed(1) is the standard text editor.
banner:
programs for printing banners at a terminal.
edterm:
ed(1) is a distraction-free writing environment.
finger:
client and server implementation for 'finger' protocol for Plan 9.
fingers:
scan a set of 'finger' endpoints and monitor them for changes.
mtte:
minimum time to ed(1).
tw:
twtxt client for Plan 9.
wikifs:
modifications to wikifs(4) to get it to produce gemtext.
zine:
serve a text zine, inspired by A New Session and dial_a_zine by caraesten.
:;
:; man 5 read
READ(5) READ(5)
NAME
read, write - transfer data from and to a file
SYNOPSIS
size[4] Tread tag[2] fid[4] offset[8] count[4]
size[4] Rread tag[2] count[4] data[count]
size[4] Twrite tag[2] fid[4] offset[8] count[4] data[count]
size[4] Rwrite tag[2] count[4]
DESCRIPTION
The read request asks for count bytes of data from the file
identified by fid, which must be opened for reading, start-
ing offset bytes after the beginning of the file. The bytes
are returned with the read reply message.
The count field in the reply indicates the number of bytes
returned. This may be less than the requested amount. If
the offset field is greater than or equal to the number of
bytes in the file, a count of zero will be returned.
For directories, read returns an integral number of direc-
tory entries exactly as in stat (see stat(5)), one for each
member of the directory. The read request message must have
offset equal to zero or the value of offset in the previous
read on the directory, plus the number of bytes returned in
the previous read. In other words, seeking other than to
the beginning is illegal in a directory (see seek(2)).
The write request asks that count bytes of data be recorded
in the file identified by fid, which must be opened for
writing, starting offset bytes after the beginning of the
file. If the file is append-only, the data will be placed
at the end of the file regardless of offset. Directories may
not be written.
The write reply records the number of bytes actually writ-
ten. It is usually an error if this is not the same as
requested.
Because 9P implementations may limit the size of individual
messages, more than one message may be produced by a single
read or write call. The iounit field returned by open(5),
if non-zero, reports the maximum size that is guaranteed to
be transferred atomically.
ENTRY POINTS
Read and write messages are generated by the corresponding
calls. Because they include an offset, the pread and pwrite
calls correspond more directly to the 9P messages. Although
seek(2) affects the offset, it does not generate a message.
#include <u.h>
#include <libc.h>
#include <bio.h>
char choice[2048];
char index[] = "/sys/games/lib/fortunes.index";
char fortunes[] = "/sys/games/lib/fortunes";
void
main(int argc, char *argv[])
{
int i;
long offs;
uchar off[4];
int ix, nix;
int newindex, oldindex;
char *p;
Dir *fbuf, *ixbuf;
Biobuf *f, g;
newindex = 0;
oldindex = 0;
ix = offs = 0;
if((f=Bopen(argc>1?argv[1]:fortunes, OREAD)) == 0){
print("Misfortune!\n");
exits("misfortune");
}
ixbuf = nil;
if(argc == 1){
ix = open(index, OREAD);
if(ix>=0){
ixbuf = dirfstat(ix);
fbuf = dirfstat(Bfildes(f));
if(ixbuf == nil || fbuf == nil){
print("Misfortune?\n");
exits("misfortune");
}
if(ixbuf->length == 0){
/* someone else is rewriting the index */
goto NoIndex;
}
oldindex = 1;
if(fbuf->mtime > ixbuf->mtime){
nix = create(index, OWRITE, 0666);
if(nix >= 0){
close(ix);
ix = nix;
newindex = 1;
oldindex = 0;
}
}
}else{
ix = create(index, OWRITE, 0666);
if(ix >= 0)
newindex = 1;
}
}
if(oldindex){
seek(ix, truerand()%(ixbuf->length/sizeof(offs))*sizeof(offs), 0);
read(ix, off, sizeof(off));
Bseek(f, off[0]|(off[1]<<8)|(off[2]<<16)|(off[3]<<24), 0);
p = Brdline(f, '\n');
if(p){
p[Blinelen(f)-1] = 0;
strcpy(choice, p);
}else
strcpy(choice, "Misfortune!");
}else{
NoIndex:
Binit(&g, ix, 1);
srand(truerand());
for(i=1;;i++){
if(newindex)
offs = Boffset(f);
p = Brdline(f, '\n');
if(p == 0)
break;
p[Blinelen(f)-1] = 0;
if(newindex){
off[0] = offs;
off[1] = offs>>8;
off[2] = offs>>16;
off[3] = offs>>24;
Bwrite(&g, off, sizeof(off));
}
if(lrand()%i==0)
strcpy(choice, p);
}
}
print("%s\n", choice);
exits(0);
}