<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<atom:link href="http://okturing.com:80/index.rss" rel="self" type="application/rss+xml" />
<title><![CDATA[OK, turing.]]></title>
<link>http://okturing.com:80/</link>
<description><![CDATA[]]></description>
<generator><![CDATA[barf]]></generator>
<lastBuildDate>
Sat, 12 Sep 2026 01:06:29 -0400
</lastBuildDate><language>en-us</language>
<item>
<guid isPermaLink="true">http://okturing.com:80/?id=21906</guid>
<pubDate>Sat, 12 Sep 2026 01:06:29 -0400</pubDate>
<title>OK, turing. 21906</title>
<link>http://okturing.com:80/?id=21906</link>
<description><![CDATA[
<pre>
Stop paying for broad, unfocused visitors. Vantovo's AI targets by specific keywords and precise locations (down to city or zip), then continuously optimizes based on what actually engages. Start a free 7-day trial—no long-term contracts, cancel anytime.

https://cutt.ly/NykOWBim 
 

</pre>
</p>]]></description></item>
<item>
<guid isPermaLink="true">http://okturing.com:80/?id=21905</guid>
<pubDate>Fri, 11 Sep 2026 20:06:14 -0400</pubDate>
<title>OK, turing. 21905</title>
<link>http://okturing.com:80/?id=21905</link>
<description><![CDATA[
<pre>
</pre>
</p>]]></description></item>
<item>
<guid isPermaLink="true">http://okturing.com:80/?id=21904</guid>
<pubDate>Fri, 11 Sep 2026 19:49:34 -0400</pubDate>
<title>OK, turing. 21904</title>
<link>http://okturing.com:80/?id=21904</link>
<description><![CDATA[
<pre>
--- /usr/glenda/src/9front/sys/src/cmd/compress/compress.c
+++ compress.c
@@ -4,7 +4,7 @@
  * Algorithm from "A Technique for High Performance Data Compression",
  * Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19.
  *
- * Usage: compress [-dfvc] [-b bits] [file ...]
+ * usage: compress [-dfvc] [-b bits] [file ...]
  * Inputs:
  *	-b:	limit the max number of bits/code.
  *	-c:	write output on stdout, don't remove original.
@@ -90,11 +90,11 @@
 typedef long code_int;
 typedef long count_int;
 
-static char rcs_ident[] = "9front native: compress.c,v 4.0 85/07/30 12:50:00 joe mama Release me";
+static char rcsident[] = "9front native: compress.c,v 4.0 85/07/30 12:50:00 joe mama Release me";
 
-uchar magic_header[] = { 0x1F, 0x9D };	/* 1F 9D */
+uchar magicheader[] = { 0x1F, 0x9D };	/* 1F 9D */
 
-int n_bits;	/* Number of bits/code */
+int nbits;	/* Number of bits/code */
 int maxbits = BITS;	/* User settable max # bits/code */
 code_int maxcode;	/* Maximum code, given n_bits */
 code_int maxmaxcode = 1 << BITS;	/* Should NEVER generate this code */
@@ -105,14 +105,14 @@
 code_int hsize = HSIZE;	/* For dynamic table sizing */
 count_int fsize;
 
-code_int free_ent = 0;			/* first unused entry */
-int exit_stat = 0;
+code_int freeent = 0;			/* first unused entry */
+int exitstat = 0;
 
 code_int getcode();
 
 int debug = 0;
 int nomagic = 0;	/* Use a 3-byte magic number header, unless old file */
-int zcat_flg = 0;	/* Write output on stdout, suppress messages */
+int zcatflg = 0;	/* Write output on stdout, suppress messages */
 int quiet = 1;	/* Don't tell me about compression */
 
 /*
@@ -119,8 +119,8 @@
  * Block compression parameters -- after all codes are used up,
  * and compression rate changes, start over.
  */
-int block_compress = BLOCK_MASK;
-int clear_flg = 0;
+int blockcompress = BLOCK_MASK;
+int clearflg = 0;
 long ratio = 0;
 count_int checkpoint = CHECK_GAP;
 
@@ -128,12 +128,12 @@
 char ofname [100];
 void (*bgnd_flag)(int);
 
-int do_decomp = 0;
+int decomp = 0;
 
 static int offset;
-long in_count = 1;	/* Length of input */
-long bytes_out;	/* Length of compressed output */
-long out_count = 0;	/* # of codes output (for debugging) */
+long incount = 1;	/* Length of input */
+long bytesout;	/* Length of compressed output */
+long outcount = 0;	/* # of codes output (for debugging) */
 
 static char buf[BITS];
 
@@ -140,18 +140,20 @@
 uchar lmask[9] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
 uchar rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
 
+Biobuf *Fin, *Fout;
+
 void
-Usage(void)
+usage(void)
 {
-	fprintf(stderr,"usage: compress [-cdfvV] [-b maxbits] [file ...]\n");
+	fprint(2, "usage: %s [-cdfvV] [-b maxbits] [file...]\n", argv0);
+	exits("usage");
 }
 
 void
 version(void)
 {
-	fprintf(stderr, "%s\n", rcs_ident);
-	fprintf(stderr, "Options: ");
-	fprintf(stderr, "BITS = %d\n", BITS);
+	fprint(2, "%s\n", rcsident);
+	fprint(2, "Options: BITS = %d\n", BITS);
 }
 
 /*
@@ -161,101 +163,84 @@
 int
 foreground(void)
 {
-	if(bgnd_flag)			/* background? */
+	char buf[64];
+
+	if(fd2path(2, buf, sizeof(buf)) < 0)
 		return 0;
-	else				/* foreground */
-		return isatty(2);	/* and stderr is a tty */
-}
 
-void
-onintr(int)
-{
-	unlink(ofname);
-	exit(1);
+	return strstr(buf, "cons") != nil;
 }
 
 void
-oops(int)		/* wild pointer -- assume bad input */
+catchnote(void *ureg, char *msg)
 {
-	if (do_decomp == 1)
-		fprintf(stderr, "uncompress: corrupt input\n");
-	unlink(ofname);
-	exit(1);
+	USED(ureg);
+	if(strncmp(msg, "sys:", 4) == 0){
+		if(decomp)
+			fprint(2, "uncompress: corrupt input\n");
+		remove(ofname);
+		exits(msg);
+	}
+
+	if(strncmp(msg, "interrupt", 9) == 0){
+		remove(ofname);
+		exits("interrupt");
+	}
+
+	noted(NDFLT);
 }
 
 void
-prratio(FILE *stream, long num, long den)
+prratio(long num, long den)
 {
-	int q;				/* Doesn't need to be long */
+	int q;
 
-	if(num > 214748L)		/* 2147483647/10000 */
-		q = num / (den / 10000L);
+	if(num > 214748L)
+		q = num / (den / 10000);
 	else
-		q = 10000L * num / den;	/* Long calculations, though */
-	if (q < 0) {
-		putc('-', stream);
+		q = 10000L * num / den;
+
+	if(q < 0){
+		fprint(2, "-");
 		q = -q;
 	}
-	fprintf(stream, "%d.%02d%%", q / 100, q % 100);
+
+	fprint(2, "%d.%02d%%", q /100, q % 100);
 }
 
 void
-cl_hash(count_int hsize)		/* reset code table */
+clhash(count_int hsize)	/* Reset code table */
 {
-	count_int *htab_p;
+	count_int *htabp;
 	long i;
 	long m1;
 
-	htab_p = htab + hsize;
-	mi = -1;
+	htabp = htab + hsize;
+	m1 = -1;
 
 	i = hsize - 16;
- 	do {				/* might use Sys V memset(3) here */
-		*(htab_p-16) = m1;
-		*(htab_p-15) = m1;
-		*(htab_p-14) = m1;
-		*(htab_p-13) = m1;
-		*(htab_p-12) = m1;
-		*(htab_p-11) = m1;
-		*(htab_p-10) = m1;
-		*(htab_p-9) = m1;
-		*(htab_p-8) = m1;
-		*(htab_p-7) = m1;
-		*(htab_p-6) = m1;
-		*(htab_p-5) = m1;
-		*(htab_p-4) = m1;
-		*(htab_p-3) = m1;
-		*(htab_p-2) = m1;
-		*(htab_p-1) = m1;
-		htab_p -= 16;
-	} while ((i -= 16) >= 0);
-	for ( i += 16; i > 0; i-- )
-		*--htab_p = m1;
-}
+	do{
+		*(htabp - 16) = m1;
+		*(htabp - 15) = m1;
+		*(htabp - 14) = m1;
+		*(htabp - 13) = m1;
+		*(htabp - 12) = m1;
+		*(htabp - 11) = m1;
+		*(htabp - 10) = m1;
+		*(htabp - 9) = m1;
+		*(htabp - 8) = m1;
+		*(htabp - 7) = m1;
+		*(htabp - 6) = m1;
+		*(htabp - 5) = m1;
+		*(htabp - 4) = m1;
+		*(htabp - 3) = m1;
+		*(htabp - 2) = m1;
+		*(htabp - 1) = m1;
+		htabp -= 16;
+	} while((i -= 16) >= 0);
 
-void
-cl_block (void)		/* table clear for block compress */
-{
-	long rat;
-
-	checkpoint = in_count + CHECK_GAP;
-	if (in_count > 0x007fffff) {	/* shift will overflow */
-		rat = bytes_out >> 8;
-		if (rat == 0)		/* Don't divide by zero */
-			rat = 0x7fffffff;
-		else
-			rat = in_count / rat;
-	} else
-		rat = (in_count << 8) / bytes_out;	/* 8 fractional bits */
-	if (rat > ratio)
-		ratio = rat;
-	else {
-		ratio = 0;
-		cl_hash((count_int)hsize);
-		free_ent = FIRST;
-		clear_flg = 1;
-		output((code_int)CLEAR);
-	}
+	for(i += 16; i > 0; i--)
+		*--htabp = m1;
 }
 
 /*
@@ -270,56 +255,60 @@
 code_int
 getcode(void)
 {
-	int r_off, bits;
+	int roff, bits;
 	code_int code;
 	static int offset = 0, size = 0;
 	static uchar buf[BITS];
-	uchar *bp = buf;
+	uchar *bp;
 
-	if ( clear_flg > 0 || offset >= size || free_ent > maxcode ) {
+	bp = buf;
+
+	if(clearflg != 0 || offset >= size || freeent > maxcode){
 		/*
 		 * If the next entry will be too big for the current code
-		 * size, then we must increase the size.  This implies reading
+		 * size, then we must increase the size. This implies reading
 		 * a new buffer full, too.
 		 */
-		if ( free_ent > maxcode ) {
-			n_bits++;
-			if ( n_bits == maxbits )
-				maxcode = maxmaxcode; /* won't get any bigger now */
+		if(freeent > maxcode){
+			nbits++;
+			if(nbits == maxbits)
+				maxcode = maxmaxcode;	/* Won't get any bigger now */
 			else
-				maxcode = MAXCODE(n_bits);
+				maxcode = MAXCODE(nbits);
 		}
-		if ( clear_flg > 0) {
-			maxcode = MAXCODE(n_bits = INIT_BITS);
-			clear_flg = 0;
+		if(clearflg > 0){
+			maxcode = MAXCODE(nbits = INIT_BITS);
+			clearflg = 0;
 		}
-		size = fread(buf, 1, n_bits, stdin);
-		if (size <= 0)
-			return -1;			/* end of file */
+		size = Bread(Fin, buf, nbits);
+		if(size <= 0)
+			return -1;
 		offset = 0;
 		/* Round size down to integral number of codes */
-		size = (size << 3) - (n_bits - 1);
+		size = (size << 3) - (nbits - 1);
 	}
-	r_off = offset;
-	bits = n_bits;
+	roff = offset;
+	bits = nbits;
 	/*
 	 * Get to the first byte.
 	 */
-	bp += (r_off >> 3);
-	r_off &= 7;
+	bp += (roff >> 3);
+	roff &= 7;
 	/* Get first part (low order bits) */
-	code = (*bp++ >> r_off);
-	bits -= (8 - r_off);
-	r_off = 8 - r_off;		/* now, offset into code word */
+	code = (*bp++ >> roff);
+	bits -=  (8 - roff);
+	roff = 8 - roff;	/* Now, offset into code word */
 	/* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
-	if (bits >= 8) {
-		code |= *bp++ << r_off;
-		r_off += 8;
+	if(bits >= 8){
+		code |= *bp++ << roff;
+		roff += 8;
 		bits -= 8;
 	}
-	/* high order bits. */
-	code |= (*bp & rmask[bits]) << r_off;
-	offset += n_bits;
+
+	/* High order bits. */
+	code |= (*bp & rmask[bits]) << roff;
+	offset += nbits;
+
 	return code;
 }
 
@@ -326,49 +315,50 @@
 void
 writeerr(void)
 {
-	perror(ofname);
-	unlink(ofname);
-	exit(1);
+	fprint(2, "%s: %r\n", ofname);
+	remove(ofname);
+	exits("write error");
 }
 
 void
 copystat(char *ifname, char *ofname)
 {
-	int mode;
-	time_t timep[2];
-	struct stat statbuf;
+	Dir *d, nd;
 
-	fclose(stdout);
-	if (stat(ifname, &statbuf)) {		/* Get stat on input file */
-		perror(ifname);
+	if((d = dirstat(ifname)) == nil){	/* Get stat on input file */
+		fprint(2, "%s: %r\n", ifname);
 		return;
 	}
-	if (!S_ISREG(statbuf.st_mode)) {
-		if (quiet)
-			fprintf(stderr, "%s: ", ifname);
-		fprintf(stderr, " -- not a regular file: unchanged");
-		exit_stat = 1;
-	} else if (exit_stat == 2 && !force) {
-		/* No compression: remove file.Z */
-		if (!quiet)
-			fprintf(stderr, " -- file unchanged");
-	} else {			/* Successful Compression */
-		exit_stat = 0;
-		mode = statbuf.st_mode & 0777;
-		if (chmod(ofname, mode))		/* Copy modes */
-			perror(ofname);
-		/* Copy ownership */
-		chown(ofname, statbuf.st_uid, statbuf.st_gid);
-		timep[0] = statbuf.st_atime;
-		timep[1] = statbuf.st_mtime;
+	if(d->mode & DMDIR){
+		if(quiet)
+			fprint(2, "%s: ", ifname);
+		fprint(2, " -- not a regular file: unchanged");
+		exitstat = 1;
+	} else if(exitstat == 2 && !force){
+		if(!quiet)
+			fprint(2, " -- file unchanged");
+	} else {	/* Successful Compression */
+		exitstat = 0;
+		nulldir(&nd);
+		nd.mode = d->mode & 0777;
 		/* Update last accessed and modified times */
-		utime(ofname, timep);
-		return;			/* success */
+		nd.mtime = d->mtime;
+		nd.atime = d->atime;
+
+		/*
+		 * Plan 9 has no chown(2) equivalent for arbitrary users;
+		 * ownership of ofname is left to whoever created it
+		 */
+		if(dirwstat(ofname, &nd) < 0)
+			fprint(2, "%s: %r\n", ofname);
+		free(d);
+		return;
 	}
 
 	/* Unsuccessful return -- one of the tests failed */
-	if (unlink(ofname))
-		perror(ofname);
+	free(d);
+	if(remove(ofname) < 0)
+		fprint(2, "%s: %r\n", ofname);
 }
 
 /*
@@ -389,32 +379,34 @@
 void
 output(code_int code)
 {
-	int r_off, bits;
+	int roff, bits;
 	char *bp;
 
-	r_off = offset;
-	bits = n_bits;
+	roff = offset;
+	bits = nbits;
 	bp = buf;
-	if (code >= 0) {
+
 		/*
 		 * byte/bit numbering on the VAX is simulated by the
 		 * following code
-		 */
-		/*
+		 *
+		 *
 		 * Get to the first byte.
 		 */
-		bp += (r_off >> 3);
-		r_off &= 7;
+	if(code >= 0){
+		bp += (roff >> 3);
+		roff &= 7;
 		/*
 		 * Since code is always >= 8 bits, only need to mask the first
 		 * hunk on the left.
 		 */
-		*bp = (*bp & rmask[r_off]) | (code << r_off) & lmask[r_off];
+		*bp = (*bp & rmask[roff]) | (code << roff) & lmask[roff];
 		bp++;
-		bits -=  8 - r_off;
-		code >>= 8 - r_off;
+		bits -= 8 - roff;
+		code >>= 8 - roff;
+
 		/* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
-		if ( bits >= 8 ) {
+		if(bits >= 8){
 			*bp++ = code;
 			code >>= 8;
 			bits -= 8;
@@ -423,14 +415,15 @@
 		if(bits)
 			*bp = code;
 
-		offset += n_bits;
-		if ( offset == (n_bits << 3) ) {
+		offset += nbits;
+		if(offset == (nbits << 3)){
 			bp = buf;
-			bits = n_bits;
-			bytes_out += bits;
-			do {
-				putchar(*bp++);
+			bits = nbits;
+			bytesout += bits;
+			do{
+				Bputc(Fout, *bp++);
 			} while(--bits);
+
 			offset = 0;
 		}
 
@@ -438,27 +431,27 @@
 		 * If the next entry is going to be too big for the code size,
 		 * then increase it, if possible.
 		 */
-		if ( free_ent > maxcode || (clear_flg > 0)) {
+		if(freeent > maxcode || (clearflg > 0)){
 			/*
 			* Write the whole buffer, because the input side won't
 			* discover the size increase until after it has read it.
 			*/
-			if ( offset > 0 ) {
-				if( fwrite( buf, 1, n_bits, stdout ) != n_bits)
+			if(offset > 0){
+				if(Bwrite(Fout, buf, nbits) != nbits)
 					writeerr();
-				bytes_out += n_bits;
+				bytesout += nbits;
 			}
 			offset = 0;
 
-			if ( clear_flg ) {
-				maxcode = MAXCODE (n_bits = INIT_BITS);
-				clear_flg = 0;
+			if(clearflg){
+				maxcode = MAXCODE(nbits = INIT_BITS);
+				clearflg = 0;
 			} else {
-				n_bits++;
-				if ( n_bits == maxbits )
+				nbits++;
+				if(nbits == maxbits)
 					maxcode = maxmaxcode;
 				else
-					maxcode = MAXCODE(n_bits);
+					maxcode = MAXCODE(nbits);
 			}
 		}
 	} else {
@@ -465,16 +458,43 @@
 		/*
 		 * At EOF, write the rest of the buffer.
 		 */
-		if ( offset > 0 )
-			fwrite( buf, 1, (offset + 7) / 8, stdout );
-		bytes_out += (offset + 7) / 8;
+		if(offset > 0)
+			Bwrite(Fout, buf, (offset + 7) / 8);
+
+		bytesout += (offset + 7) / 8;
 		offset = 0;
-		fflush( stdout );
-		if( ferror( stdout ) )
+
+		if(Bflush(Fout) < 0)
 			writeerr();
 	}
 }
 
+void
+clblock(void)	/* table clear for block compress */
+{
+	long rat;
+
+	checkpoint = incount + CHECK_GAP;
+
+	if(incount > 0x007fffff){
+		rat = bytesout >> 8;
+		if(rat == 0)
+			rat = 0x7fffffff;
+		else
+			rat = incount / rat;
+	} else
+		rat = (incount << 8) / bytesout;
+	if(rat > ratio)
+		ratio = rat;
+	else {
+		ratio = 0;
+		clhash((count_int)hsize);
+		freeent = FIRST;
+		clearflg = 1;
+		output((code_int)CLEAR);
+	}
+}
+
 /*
  * compress stdin to stdout
  *
@@ -491,89 +511,88 @@
  * questions about this implementation to ames!jaw.
  */
 void
-compress(void)
+compress(Biobuf *fin, Biobuf *fout)
 {
-	code_int ent, hsize_reg;
+	code_int ent, hsizereg;
 	code_int i;
 	int c, disp, hshift;
 	long fcode;
 
-	if (nomagic == 0) {
-		putchar(magic_header[0]);
-		putchar(magic_header[1]);
-		putchar((char)(maxbits | block_compress));
-		if(ferror(stdout))
-			writeerr();
+	Fin = fin;
+	Fout = fout;
+
+	if(nomagic == 0){
+		Bputc(Fout, magicheader[0]);
+		Bputc(Fout, magicheader[1]);
+		Bputc(Fout, (char)(maxbits | blockcompress));
 	}
 	offset = 0;
-	bytes_out = 3;		/* includes 3-byte header mojo */
-	out_count = 0;
-	clear_flg = 0;
+	bytesout = 3;
+	outcount = 0;
+	clearflg = 0;
 	ratio = 0;
-	in_count = 1;
+	incount = 1;
 	checkpoint = CHECK_GAP;
-	maxcode = MAXCODE(n_bits = INIT_BITS);
-	free_ent = (block_compress? FIRST: 256);
+	maxcode = MAXCODE(nbits = INIT_BITS);
+	freeent = (blockcompress ? FIRST : 256);
 
-	ent = getchar ();
+	ent = Bgetc(Fin);
 
 	hshift = 0;
-	for (fcode = (long)hsize;  fcode < 65536L; fcode *= 2)
+	for(fcode = (long)hsize; fcode < 65536L; fcode *= 2)
 		hshift++;
-	hshift = 8 - hshift;		/* set hash code range bound */
+	hshift = 8 - hshift;
 
-	hsize_reg = hsize;
-	cl_hash( (count_int) hsize_reg);		/* clear hash table */
+	hsizereg = hsize;
+	clhash((count_int)hsizereg);
 
-	while ((c = getchar()) != EOF) {
-		in_count++;
-		fcode = (long) (((long) c << maxbits) + ent);
-	 	i = ((c << hshift) ^ ent);	/* xor hashing */
+	while((c = Bgetc(Fin)) != -1){
+		incount++;
+		fcode = (long)(((long)c << maxbits) + ent);
+		i = ((c << hshift) ^ ent);
 
-		if (Htabof (i) == fcode) {
+		if(Htabof(i) == fcode){
 			ent = Codetabof(i);
 			continue;
-		} else if ((long)Htabof(i) < 0 )	/* empty slot */
+		} else if((long)Htabof(i) < 0)
 			goto nomatch;
-	 	disp = hsize_reg - i;	/* secondary hash (after G. Knott) */
-		if (i == 0)
+
+		disp = hsizereg - i;
+		if(i == 0)
 			disp = 1;
+
 probe:
-		if ((i -= disp) < 0)
-			i += hsize_reg;
+	if((i -= disp) < 0)
+		i+= hsizereg;
+	if(Htabof(i) == fcode){
+		ent = Codetabof(i);
+		continue;
+	}
+	if((long)Htabof(i) > 0)
+		goto probe;
 
-		if (Htabof (i) == fcode) {
-			ent = Codetabof(i);
-			continue;
-		}
-		if ((long)Htabof(i) > 0)
-			goto probe;
 nomatch:
 		output((code_int)ent);
-		out_count++;
-	 	ent = c;
-		if (free_ent < maxmaxcode) {
-	 		Codetabof(i) = free_ent++;	/* code -> hashtable */
+		outcount++;
+		ent = c;
+
+		if(freeent < maxmaxcode){
+			Codetabof(i) = freeent++;
 			Htabof(i) = fcode;
-		} else if ((count_int)in_count >= checkpoint && block_compress)
-			cl_block ();
+		} else if((count_int)incount >= checkpoint && blockcompress)
+			clblock();
 	}
-	/*
-	* Put out the final code.
-	*/
-	output( (code_int)ent );
-	out_count++;
-	output( (code_int)-1 );
 
-	/*
-	* Print out stats on stderr
-	*/
-	if(zcat_flg == 0 && !quiet) {
-	fprintf( stderr, "Compression: " );
-	prratio( stderr, in_count-bytes_out, in_count );
+	output((code_int)ent);
+	outcount++;
+	output((code_int)-1);
+
+	if(zcatflg == 0 && !quiet){
+		fprint(2, "Compression: ");
+		prratio(incount - bytesout, incount);
 	}
-	if(bytes_out > in_count)	/* exit(2) if no savings */
-		exit_stat = 2;
+	if(bytesout > incount)
+		exitstat = 2;
 }
 
 /*
@@ -583,44 +602,46 @@
  * with those of the compress() routine.  See the definitions above.
  */
 void
-decompress(void)
+decompress(Biobuf *fin, Biobuf *fout)
 {
 	int finchar;
 	code_int code, oldcode, incode;
 	uchar *stackp;
 
+	Fin = fin;
+	Fout = fout;
+
 	/*
 	* As above, initialize the first 256 entries in the table.
 	*/
-	maxcode = MAXCODE(n_bits = INIT_BITS);
-	for (code = 255; code >= 0; code--) {
+	maxcode = MAXCODE(nbits = INIT_BITS);
+	for(code = 255; code >= 0; code--){
 		Tab_prefixof(code) = 0;
 		Tab_suffixof(code) = (uchar)code;
 	}
-	free_ent = (block_compress? FIRST: 256);
+	freeent = (blockcompress ? FIRST : 256);
 
 	finchar = oldcode = getcode();
-	if(oldcode == -1)		/* EOF already? */
-		return;			/* Get out of here */
-	putchar((char)finchar);		/* first code must be 8 bits = char */
-	if(ferror(stdout))		/* Crash if can't write */
-		writeerr();
+	if(oldcode == -1)	/* EOF already? */
+		return;	/* Get out of here */
+	Bputc(Fout, (char)finchar);	/* First code must be 8 bits = char */
 	stackp = De_stack;
 
-	while ((code = getcode()) > -1) {
-		if ((code == CLEAR) && block_compress) {
-			for (code = 255; code >= 0; code--)
+	while((code = getcode()) > -1){
+		if((code == CLEAR) && blockcompress){
+			for(code = 255; code >= 0; code--)
 				Tab_prefixof(code) = 0;
-			clear_flg = 1;
-			free_ent = FIRST - 1;
-			if ((code = getcode()) == -1)	/* O, untimely death! */
-				break;
+		clearflg = 1;
+		freeent = FIRST -1;
+		if((code = getcode()) == -1)
+			break;
 		}
-		incode = code;
+
 		/*
 		 * Special case for KwKwK string.
 		 */
-		if (code >= free_ent) {
+		incode = code;
+		if(code >= freeent){
 			*stackp++ = finchar;
 			code = oldcode;
 		}
@@ -628,7 +649,7 @@
 		/*
 		 * Generate output characters in reverse order
 		 */
-		while (code >= 256) {
+		while(code >= 256){
 			*stackp++ = Tab_suffixof(code);
 			code = Tab_prefixof(code);
 		}
@@ -637,25 +658,25 @@
 		/*
 		 * And put them out in forward order
 		 */
-		do {
-			putchar(*--stackp);
-		} while (stackp > De_stack);
+		do{
+			Bputc(Fout, *--stackp);
+		} while(stackp > De_stack);
 
 		/*
 		 * Generate the new entry.
 		 */
-		if ( (code=free_ent) < maxmaxcode ) {
+		if((code = freeent) < maxmaxcode){
 			Tab_prefixof(code) = (ushort)oldcode;
 			Tab_suffixof(code) = finchar;
-			free_ent = code+1;
+			freeent = code + 1;
 		}
+
 		/*
 		 * Remember previous code.
 		 */
 		oldcode = incode;
 	}
-	fflush(stdout);
-	if(ferror(stdout))
+	if(Bflush(Fout) < 0)
 		writeerr();
 }
 
@@ -663,70 +684,42 @@
 main(int argc, char **argv)
 {
 	int overwrite;
-	char tempname[512];
+	char tmpname[512];
 	char **filelist, **fileptr;
 	char *cp;
-	struct stat statbuf;
+	Dir *d;
+	int fd;
+	char response[2];
+	int consfd;
 
 	overwrite = 0;	/* Do not overwrite unless given -f flag */
+	argv0 = argv[0];
 
-	if ( (bgnd_flag = signal ( SIGINT, SIG_IGN )) != SIG_IGN ) {
-		signal(SIGINT, onintr);
-		signal(SIGSEGV, oops);
-	}
+	notify(catchnote);
 
-	filelist = fileptr = (char **)(malloc(argc * sizeof(*argv)));
-	*filelist = NULL;
-
-	if((cp = strrchr(argv[0], '/')) != 0)
+	if((cp = strrchr(argv[0], '/')) != nil)
 		cp++;
 	else
 		cp = argv[0];
 	if(strcmp(cp, "uncompress") == 0)
-		do_decomp = 1;
-	else if(strcmp(cp, "zcat") == 0) {
-		do_decomp = 1;
-		zcat_flg = 1;
+		decomp = 1;
+	if(strcmp(cp, "zcat") == 0){
+		decomp = 1;
+		zcatflg = 1;
 	}
 
-	/*
-	 * Argument Processing
-	 * All flags are optional.
-	 * -C	generate output compatible with compress 2.0.
-	 * -D	debug
-	 * -V	print Version; debug verbose
-	 * -b maxbits	maxbits.  If -b is specified, then maxbits MUST be
-	 *		given also.
-	 * -c	cat all output to stdout
-	 * -d	do_decomp
-	 * -f	force overwrite of output file
-	 * -n	no header: useful to uncompress old files
-	 * -v	unquiet
-	 * if a string is left, must be an input filename.
-	 */
-	for (argc--, argv++; argc > 0; argc--, argv++) {
-	if (**argv == '-') {	/* A flag argument */
-		while (*++(*argv)) {	/* Process all flags in this arg */
-		switch (**argv) {
+	ARGBEGIN{
 		case 'C':
-			block_compress = 0;
+			blockcompress = 0;
 			break;
-		case 'V':
-			version();
-			break;
 		case 'b':
-			if (!ARGVAL()) {
-				fprintf(stderr, "Missing maxbits\n");
-				Usage();
-				exit(1);
-			}
-			maxbits = atoi(*argv);
-			goto nextarg;
+			maxbits = atoi(EARGF(usage()));
+			break;
 		case 'c':
-			zcat_flg = 1;
+			zcatflg = 1;
 			break;
 		case 'd':
-			do_decomp = 1;
+			decomp = 1;
 			break;
 		case 'f':
 		case 'F':
@@ -742,185 +735,168 @@
 		case 'v':
 			quiet = 0;
 			break;
+		case 'V':
+			version();
+			break;
 		default:
-			fprintf(stderr, "Unknown flag: '%c'; ", **argv);
-			Usage();
-			exit(1);
-		}
-		}
-	} else {			/* Input file name */
-		*fileptr++ = *argv;	/* Build input file list */
-		*fileptr = NULL;
-		/* process nextarg; */
-	}
-nextarg:
-		continue;
-	}
+			usage();
+	}ARGEND
 
-	if(maxbits < INIT_BITS) maxbits = INIT_BITS;
-	if (maxbits > BITS) maxbits = BITS;
+	/*
+	 * ARGBEGIN/ARGEND leaves argv[] holding just the non-flag
+	 * filename arguments, nil-terMinated
+	 */
+	fileptr = argv;
+	filelist = fileptr;
+
+	if(maxbits < INIT_BITS)
+		maxbits = INIT_BITS;
+	if(maxbits > BITS)
+		maxbits = BITS;
+
 	maxmaxcode = 1 << maxbits;
 
-	if (*filelist != NULL) {
-	for (fileptr = filelist; *fileptr; fileptr++) {
-		exit_stat = 0;
-		if (do_decomp != 0) {			/* DECOMPRESSION */
-		/* Check for .Z suffix */
-		if (strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") != 0) {
-			/* No .Z: tack one on */
-			strcpy(tempname, *fileptr);
-			strcat(tempname, ".Z");
-			*fileptr = tempname;
-		}
-		/* Open input file */
-		if ((freopen(*fileptr, "r", stdin)) == NULL) {
-			perror(*fileptr);
-			continue;
-		}
-		/* Check the magic number */
-		if (nomagic == 0) {
-			if ((getchar() != (magic_header[0] & 0xFF))
-			|| (getchar() != (magic_header[1] & 0xFF))) {
-				fprintf(stderr, "%s: not in compressed format\n",
-					*fileptr);
-				continue;
-			}
-			maxbits = getchar();	/* set -b from file */
-			block_compress = maxbits & BLOCK_MASK;
-			maxbits &= BIT_MASK;
-			maxmaxcode = 1 << maxbits;
-			if(maxbits > BITS) {
-				fprintf(stderr,
-		"%s: compressed with %d bits, can only handle %d bits\n",
-					*fileptr, maxbits, BITS);
-				continue;
-			}
-		}
-		/* Generate output filename */
-		strcpy(ofname, *fileptr);
-		ofname[strlen(*fileptr) - 2] = '\0';  /* Strip off .Z */
-		} else {				/* COMPRESSION */
-		if (strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") == 0) {
-			fprintf(stderr,
-				"%s: already has .Z suffix -- no change\n",
-				*fileptr);
-			continue;
-		}
-		/* Open input file */
-		if ((freopen(*fileptr, "r", stdin)) == NULL) {
-			perror(*fileptr);
-			continue;
-		}
-		(void) stat(*fileptr, &statbuf);
-		fsize = (long) statbuf.st_size;
-		/*
-		 * tune hash table size for small files -- ad hoc,
-		 * but the sizes match earlier #defines, which
-		 * serve as upper bounds on the number of output codes.
-		 */
-		hsize = HSIZE;
-		if (fsize < (1 << 12))
-			hsize = Min(5003, HSIZE);
-		else if (fsize < (1 << 13))
-			hsize = Min(9001, HSIZE);
-		else if (fsize < (1 << 14))
-			hsize = Min (18013, HSIZE);
-		else if (fsize < (1 << 15))
-			hsize = Min (35023, HSIZE);
-		else if (fsize < 47000)
-			hsize = Min (50021, HSIZE);
+	if(*filelist != nil){
+		for(fileptr = filelist; *fileptr; fileptr++){
+			exitstat = 0;
+			if(decomp != 0){ /* Decompression */
+				if(strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") != 0){
+					snprint(tmpname, sizeof(tmpname), "%s.Z", *fileptr);
+					*fileptr = tmpname;
+				}
+				if((Fin = Bopen(*fileptr, OREAD)) == nil){
+					fprint(2, "%s: %r\n", *fileptr);
+					continue;
+				}
+				if(nomagic == 0){
+					if(Bgetc(Fin) != (magicheader[0] & 0xff)
+					|| Bgetc(Fin) != (magicheader[1] & 0xff)){
+						fprint(2, "%s: not in compressed format\n", *fileptr);
+						Bterm(Fin);
+						continue;
+					}
+					maxbits = Bgetc(Fin);
+					blockcompress = maxbits & BLOCK_MASK;
+					maxbits &= BIT_MASK;
+					maxmaxcode = 1 << maxbits;
+					if(maxbits > BITS){
+						fprint(2, "%s: compressed with %d bits, can only handle %d bits\n",
+							*fileptr, maxbits, BITS);
+						Bterm(Fin);
+						continue;
+					}
+				}
+				strcpy(ofname, *fileptr);
+				ofname[strlen(*fileptr) - 2] = '\0'; /* Strip ending .Z */
+			} else { /* Compression */
+				if(strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") == 0){
+					fprint(2, "%s: already has .Z suffix -- no change\n", *fileptr);
+					continue;
+				}
+				if((Fin = Bopen(*fileptr, OREAD)) == nil){
+					fprint(2, "%s: %r\n", *fileptr);
+					continue;
+				}
+				if((d = dirstat(*fileptr)) != nil){
+					fsize = d->length;
+					free(d);
+				} else
+					fsize = 0;
 
-		/* Generate output filename */
-		strcpy(ofname, *fileptr);
-		if ((cp=strrchr(ofname,'/')) != NULL)
-			cp++;
-		else
-			cp = ofname;
-		/*
-		 *** changed 12 to 25;  should be NAMELEN-3, but I don't want
-		 * to fight the headers.	ehg 5 Nov 92 **
-		 */
-		if (strlen(cp) > 25) {
-			fprintf(stderr, "%s: filename too long to tack on .Z\n",
-				cp);
-			continue;
-		}
-		strcat(ofname, ".Z");
-		}
-		/* Check for overwrite of existing file */
-		if (overwrite == 0 && zcat_flg == 0 &&
-		   stat(ofname, &statbuf) == 0) {
-			char response[2];
+					hsize = HSIZE;
+					if(fsize < (1 << 12))
+						hsize = Min(5003, HSIZE);
+					else if(fsize < (1 << 13))
+						hsize = Min(9001, HSIZE);
+					else if(fsize < (1 << 14))
+						hsize = Min(18013, HSIZE);
+					else if(fsize < (1 << 15))
+						hsize = Min (35023, HSIZE);
+					else if (fsize < 47000)
+						hsize = Min (50021, HSIZE);
 
-			response[0] = 'n';
-			fprintf(stderr, "%s already exists;", ofname);
-			if (foreground()) {
-				fprintf(stderr,
-				    " do you wish to overwrite %s (y or n)? ",
-					ofname);
-				fflush(stderr);
-				(void) read(2, response, 2);
-				while (response[1] != '\n')
-					if (read(2, response+1, 1) < 0) {
-						/* Ack! */
-						perror("stderr");
-						break;
+					snprint(ofname, sizeof(ofname), "%s.Z", *fileptr);
+			}
+			if(overwrite == 0 && zcatflg == 0 && (d = dirstat(ofname)) != nil){
+				free(d);
+				response[0] = 'n';
+				fprint(2, "%s already exists;", ofname);
+				if(foreground() != 0){
+					if((consfd = open("/dev/cons", OREAD)) >= 0){
+					fprint(2, " do you wish to overwrite %s (y or n)?", ofname);
+						(void) read(consfd, response, 2);
+						while(response[1] != '\n')
+							if(read(2, response + 1, 1) < 0){
+								fprint(2, "/dev/cons: %r/n");
+								break;;
+						}
+					close(consfd);
 					}
+				}
+				if(response[0] != 'y'){
+					fprint(2, "\tnot overwritten\n");
+					Bterm(Fin);
+					continue;
+				}
 			}
-			if (response[0] != 'y') {
-				fprintf(stderr, "\tnot overwritten\n");
-				continue;
-			}
-		}
-		if(zcat_flg == 0) {		/* Open output file */
-			if (freopen(ofname, "w", stdout) == NULL) {
-				perror(ofname);
-				continue;
-			}
-			if(!quiet)
-				fprintf(stderr, "%s: ", *fileptr);
-		}
+			if(zcatflg == 0){
+				fd = create(ofname, OWRITE, 0666);
+				if(fd < 0 || (Fout = Bfdopen(fd, OWRITE)) == nil){
+					fprint(2, "%s: %r\n", ofname);
+					Bterm(Fin);
+					continue;
+				}
+				if(!quiet)
+					fprint(2, "%s: ", *fileptr);
+			} else
+				Fout = Bfdopen(1, OWRITE);
+			if(decomp == 0)
+				compress(Fin, Fout);
+			else
+				decompress(Fin, Fout);
 
-		/* Actually do the compression/decompression */
-		if (do_decomp == 0)
-			compress();
-		else
-			decompress();
-		if(zcat_flg == 0) {
-			copystat(*fileptr, ofname);	/* Copy stats */
-			if (exit_stat == 1 || !quiet)
-				putc('\n', stderr);
+			Bterm(Fin);
+			Bflush(Fout);
+			if(zcatflg == 0){
+				Bterm(Fout);
+				copystat(*fileptr, ofname);
+				if(exitstat == 1 || !quiet)
+					fprint(2, "\n");
+			} else
+				Bterm(Fout);
 		}
-	}
-	} else {		/* Standard input */
-	if (do_decomp == 0) {
-		compress();
-		if(!quiet)
-			putc('\n', stderr);
 	} else {
-		/* Check the magic number */
-		if (nomagic == 0) {
-		if ((getchar()!=(magic_header[0] & 0xFF))
-		 || (getchar()!=(magic_header[1] & 0xFF))) {
-			fprintf(stderr, "stdin: not in compressed format\n");
-			exit(1);
+		Fin = Bfdopen(0, OREAD);
+		Fout = Bfdopen(1, OWRITE);
+		if(decomp == 0){
+			compress(Fin, Fout);
+			if(!quiet)
+				fprint(2, "\n");
+		} else {
+			if(nomagic == 0){
+				if(Bgetc(Fin) != (magicheader[0] & 0xff)
+				|| Bgetc(Fin) != (magicheader[1] & 0xff)){
+					fprint(2, "stdin: not in compressed format\n");
+					exits("format");
+				}
+				maxbits = Bgetc(Fin);
+				blockcompress = maxbits & BLOCK_MASK;
+				maxbits &= BIT_MASK;
+				maxmaxcode = 1 << maxbits;
+				fsize = 100000;
+				if(maxbits > BITS){
+					fprint(2, "stdin: compressed with %d bits, can only handle %d bits\n",
+						maxbits, BITS);
+					exits("format");
+				}
+			}
+			decompress(Fin, Fout);
 		}
-		maxbits = getchar();	/* set -b from file */
-		block_compress = maxbits & BLOCK_MASK;
-		maxbits &= BIT_MASK;
-		maxmaxcode = 1 << maxbits;
-		fsize = 100000;		/* assume stdin large for USERMEM */
-		if(maxbits > BITS) {
-			fprintf(stderr,
-			"stdin: compressed with %d bits, can only handle %d bits\n",
-			maxbits, BITS);
-			exit(1);
-		}
-		}
-		decompress();
+		Bflush(Fout);
+		Bterm(Fin);
+		Bterm(Fout);
 	}
-	}
-	exit(exit_stat);
+	exits(exitstat ? "error": nil);
 }
 
 /*

</pre>
</p>]]></description></item>
<item>
<guid isPermaLink="true">http://okturing.com:80/?id=21903</guid>
<pubDate>Fri, 11 Sep 2026 19:48:34 -0400</pubDate>
<title>OK, turing. 21903</title>
<link>http://okturing.com:80/?id=21903</link>
<description><![CDATA[
<pre>
--- /usr/glenda/src/9front/sys/src/cmd/compress/compress.c
+++ compress.c
@@ -26,9 +26,9 @@
  * Algorithm:
  * 	Modified Lempel-Ziv method (LZW).  Basically finds common
  * substrings and replaces them with a variable size code.  This is
- * deterministic, and can be done on the fly.  Thus, the decompression
+ * deterMinistic, and can be done on the fly.  Thus, the decompression
  * procedure needs no input table, but tracks the way the table was built.
-
+ *
  * Authors:	Spencer W. Thomas	(decvax!harpo!utah-cs!utah-gr!thomas)
  *		Jim McKie		(decvax!mcvax!jim)
  *		Steve Davies		(decvax!vax135!petsd!peora!srd)
@@ -36,138 +36,640 @@
  *		James A. Woods		(decvax!ihnp4!ames!jaw)
  *		Joe Orost		(decvax!vax135!petsd!joe)
  */
-#define _PLAN9_SOURCE
-
 #include <u.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <libc.h>
+#include <bio.h>
 
-#define	min(a,b)	((a>b) ? b : a)
+#define	Min(a,b)	((a>b) ? b : a)
 
 #define BITS	16
-#define HSIZE	69001		/* 95% occupancy */
+#define HSIZE	69001	/* 95% occupancy */
 
-/*
- * a code_int must be able to hold 2**BITS values of type int, and also -1
- */
-typedef long	code_int;
-typedef long	count_int;
+#define CHECK_GAP	10000	/* Ratio check interval */
 
-static char rcs_ident[] = "$Header: compress.c,v 4.0 85/07/30 12:50:00 joe Release $";
-
-uchar magic_header[] = { 0x1F, 0x9D };	/* 1F 9D */
-
 /* Defines for third byte of header */
 #define BIT_MASK	0x1f
 #define BLOCK_MASK	0x80
-/* Masks 0x40 and 0x20 are free.  I think 0x20 should mean that there is
-	a fourth header byte (for expansion).
-*/
-#define INIT_BITS 9			/* initial number of bits/code */
 
-void onintr(int);
-void oops(int);
+/*
+ * Masks 0x40 and 0x20 are free.
+ * I think 0x20 should mean that there is a fourth header byte
+ * (for expansion).
+ */
+#define INIT_BITS 9	/* initial number of bits/code */
 
 #define ARGVAL() (*++(*argv) || (--argc && *++argv))
 
-int n_bits;				/* number of bits/code */
-int maxbits = BITS;			/* user settable max # bits/code */
-code_int maxcode;			/* maximum code, given n_bits */
-code_int maxmaxcode = 1 << BITS;	/* should NEVER generate this code */
-
 #define MAXCODE(n_bits)	((1 << (n_bits)) - 1)
 
-count_int htab[HSIZE];
-ushort codetab[HSIZE];
+#define Htabof(i)	htab[i]
+#define Codetabof(i)	codetab[i]
 
-#define htabof(i)	htab[i]
-#define codetabof(i)	codetab[i]
-
-code_int hsize = HSIZE;			/* for dynamic table sizing */
-count_int fsize;
-
 /*
  * To save much memory, we overlay the table used by compress() with those
- * used by decompress().  The tab_prefix table is the same size and type
- * as the codetab.  The tab_suffix table needs 2**BITS characters.  We
- * get this from the beginning of htab.  The output stack uses the rest
- * of htab, and contains characters.  There is plenty of room for any
+ * used by decompress(). The tab_prefix table is the same size and type
+ * as the codetab. The tab_suffix table needs 2**BITS characters. We
+ * get this from the beginning of htab. The output stack uses the rest
+ * of htab, and contains characters. There is plenty of room for any
  * possible stack (stack used to be 8000 characters).
  */
+#define Tab_prefixof(i)	Codetabof(i)
+#define Tab_suffixof(i)	((uchar *)(htab))[i]
+#define De_stack	((uchar *)&Tab_suffixof(1<<BITS))
 
-#define tab_prefixof(i)	codetabof(i)
-#define tab_suffixof(i)	((uchar *)(htab))[i]
-#define de_stack		((uchar *)&tab_suffixof(1<<BITS))
+/*
+ * The next two codes should not be changed lightly, as they must not
+ * lie within the contiguous general code space.
+ */
+#define FIRST	257	/* First free entry */
+#define	CLEAR	256	/* Table clear output code */
 
+/*
+ * A code_int must be able to hold 2**BITS values of type int, and also -1
+ */
+typedef long code_int;
+typedef long count_int;
+
+static char rcs_ident[] = "9front native: compress.c,v 4.0 85/07/30 12:50:00 joe mama Release me";
+
+uchar magic_header[] = { 0x1F, 0x9D };	/* 1F 9D */
+
+int n_bits;	/* Number of bits/code */
+int maxbits = BITS;	/* User settable max # bits/code */
+code_int maxcode;	/* Maximum code, given n_bits */
+code_int maxmaxcode = 1 << BITS;	/* Should NEVER generate this code */
+
+count_int htab[HSIZE];
+ushort codetab[HSIZE];
+
+code_int hsize = HSIZE;	/* For dynamic table sizing */
+count_int fsize;
+
 code_int free_ent = 0;			/* first unused entry */
 int exit_stat = 0;
 
 code_int getcode();
 
-void
-Usage(void)
-{
-#ifdef DEBUG
-	fprintf(stderr,"usage: compress [-cdfDV] [-b maxbits] [file ...]\n");
-#else
-	fprintf(stderr,"usage: compress [-cdfvV] [-b maxbits] [file ...]\n");
-#endif /* DEBUG */
-}
-
 int debug = 0;
 int nomagic = 0;	/* Use a 3-byte magic number header, unless old file */
 int zcat_flg = 0;	/* Write output on stdout, suppress messages */
-int quiet = 1;		/* don't tell me about compression */
+int quiet = 1;	/* Don't tell me about compression */
 
 /*
- * block compression parameters -- after all codes are used up,
+ * Block compression parameters -- after all codes are used up,
  * and compression rate changes, start over.
  */
 int block_compress = BLOCK_MASK;
 int clear_flg = 0;
 long ratio = 0;
-#define CHECK_GAP 10000	/* ratio check interval */
 count_int checkpoint = CHECK_GAP;
-/*
- * the next two codes should not be changed lightly, as they must not
- * lie within the contiguous general code space.
- */
-#define FIRST	257	/* first free entry */
-#define	CLEAR	256	/* table clear output code */
 
 int force = 0;
 char ofname [100];
-#ifdef DEBUG
-int verbose = 0;
-#endif /* DEBUG */
 void (*bgnd_flag)(int);
 
 int do_decomp = 0;
 
-void decompress(void);
-void compress(void);
-void output(code_int);
-void writeerr(void);
-void copystat(char*, char*);
-void cl_block(void);
-void cl_hash(long);
-void prratio(FILE*, long, long);
-void version(void);
+static int offset;
+long in_count = 1;	/* Length of input */
+long bytes_out;	/* Length of compressed output */
+long out_count = 0;	/* # of codes output (for debugging) */
 
+static char buf[BITS];
+
+uchar lmask[9] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
+uchar rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
+
 void
+Usage(void)
+{
+	fprintf(stderr,"usage: compress [-cdfvV] [-b maxbits] [file ...]\n");
+}
+
+void
+version(void)
+{
+	fprintf(stderr, "%s\n", rcs_ident);
+	fprintf(stderr, "Options: ");
+	fprintf(stderr, "BITS = %d\n", BITS);
+}
+
+/*
+ * This routine returns 1 if we are running in the foreground and stderr
+ * is a tty.
+ */
+int
+foreground(void)
+{
+	if(bgnd_flag)			/* background? */
+		return 0;
+	else				/* foreground */
+		return isatty(2);	/* and stderr is a tty */
+}
+
+void
+onintr(int)
+{
+	unlink(ofname);
+	exit(1);
+}
+
+void
+oops(int)		/* wild pointer -- assume bad input */
+{
+	if (do_decomp == 1)
+		fprintf(stderr, "uncompress: corrupt input\n");
+	unlink(ofname);
+	exit(1);
+}
+
+void
+prratio(FILE *stream, long num, long den)
+{
+	int q;				/* Doesn't need to be long */
+
+	if(num > 214748L)		/* 2147483647/10000 */
+		q = num / (den / 10000L);
+	else
+		q = 10000L * num / den;	/* Long calculations, though */
+	if (q < 0) {
+		putc('-', stream);
+		q = -q;
+	}
+	fprintf(stream, "%d.%02d%%", q / 100, q % 100);
+}
+
+void
+cl_hash(count_int hsize)		/* reset code table */
+{
+	count_int *htab_p;
+	long i;
+	long m1;
+
+	htab_p = htab + hsize;
+	mi = -1;
+
+	i = hsize - 16;
+ 	do {				/* might use Sys V memset(3) here */
+		*(htab_p-16) = m1;
+		*(htab_p-15) = m1;
+		*(htab_p-14) = m1;
+		*(htab_p-13) = m1;
+		*(htab_p-12) = m1;
+		*(htab_p-11) = m1;
+		*(htab_p-10) = m1;
+		*(htab_p-9) = m1;
+		*(htab_p-8) = m1;
+		*(htab_p-7) = m1;
+		*(htab_p-6) = m1;
+		*(htab_p-5) = m1;
+		*(htab_p-4) = m1;
+		*(htab_p-3) = m1;
+		*(htab_p-2) = m1;
+		*(htab_p-1) = m1;
+		htab_p -= 16;
+	} while ((i -= 16) >= 0);
+	for ( i += 16; i > 0; i-- )
+		*--htab_p = m1;
+}
+
+void
+cl_block (void)		/* table clear for block compress */
+{
+	long rat;
+
+	checkpoint = in_count + CHECK_GAP;
+	if (in_count > 0x007fffff) {	/* shift will overflow */
+		rat = bytes_out >> 8;
+		if (rat == 0)		/* Don't divide by zero */
+			rat = 0x7fffffff;
+		else
+			rat = in_count / rat;
+	} else
+		rat = (in_count << 8) / bytes_out;	/* 8 fractional bits */
+	if (rat > ratio)
+		ratio = rat;
+	else {
+		ratio = 0;
+		cl_hash((count_int)hsize);
+		free_ent = FIRST;
+		clear_flg = 1;
+		output((code_int)CLEAR);
+	}
+}
+
+/*
+ * TAG( getcode )
+ *
+ * Read one code from the standard input.  If EOF, return -1.
+ * Inputs:
+ * 	stdin
+ * Outputs:
+ * 	code or -1 is returned.
+ */
+code_int
+getcode(void)
+{
+	int r_off, bits;
+	code_int code;
+	static int offset = 0, size = 0;
+	static uchar buf[BITS];
+	uchar *bp = buf;
+
+	if ( clear_flg > 0 || offset >= size || free_ent > maxcode ) {
+		/*
+		 * If the next entry will be too big for the current code
+		 * size, then we must increase the size.  This implies reading
+		 * a new buffer full, too.
+		 */
+		if ( free_ent > maxcode ) {
+			n_bits++;
+			if ( n_bits == maxbits )
+				maxcode = maxmaxcode; /* won't get any bigger now */
+			else
+				maxcode = MAXCODE(n_bits);
+		}
+		if ( clear_flg > 0) {
+			maxcode = MAXCODE(n_bits = INIT_BITS);
+			clear_flg = 0;
+		}
+		size = fread(buf, 1, n_bits, stdin);
+		if (size <= 0)
+			return -1;			/* end of file */
+		offset = 0;
+		/* Round size down to integral number of codes */
+		size = (size << 3) - (n_bits - 1);
+	}
+	r_off = offset;
+	bits = n_bits;
+	/*
+	 * Get to the first byte.
+	 */
+	bp += (r_off >> 3);
+	r_off &= 7;
+	/* Get first part (low order bits) */
+	code = (*bp++ >> r_off);
+	bits -= (8 - r_off);
+	r_off = 8 - r_off;		/* now, offset into code word */
+	/* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
+	if (bits >= 8) {
+		code |= *bp++ << r_off;
+		r_off += 8;
+		bits -= 8;
+	}
+	/* high order bits. */
+	code |= (*bp & rmask[bits]) << r_off;
+	offset += n_bits;
+	return code;
+}
+
+void
+writeerr(void)
+{
+	perror(ofname);
+	unlink(ofname);
+	exit(1);
+}
+
+void
+copystat(char *ifname, char *ofname)
+{
+	int mode;
+	time_t timep[2];
+	struct stat statbuf;
+
+	fclose(stdout);
+	if (stat(ifname, &statbuf)) {		/* Get stat on input file */
+		perror(ifname);
+		return;
+	}
+	if (!S_ISREG(statbuf.st_mode)) {
+		if (quiet)
+			fprintf(stderr, "%s: ", ifname);
+		fprintf(stderr, " -- not a regular file: unchanged");
+		exit_stat = 1;
+	} else if (exit_stat == 2 && !force) {
+		/* No compression: remove file.Z */
+		if (!quiet)
+			fprintf(stderr, " -- file unchanged");
+	} else {			/* Successful Compression */
+		exit_stat = 0;
+		mode = statbuf.st_mode & 0777;
+		if (chmod(ofname, mode))		/* Copy modes */
+			perror(ofname);
+		/* Copy ownership */
+		chown(ofname, statbuf.st_uid, statbuf.st_gid);
+		timep[0] = statbuf.st_atime;
+		timep[1] = statbuf.st_mtime;
+		/* Update last accessed and modified times */
+		utime(ofname, timep);
+		return;			/* success */
+	}
+
+	/* Unsuccessful return -- one of the tests failed */
+	if (unlink(ofname))
+		perror(ofname);
+}
+
+/*
+ * TAG( output )
+ *
+ * Output the given code.
+ * Inputs:
+ * 	code:	A n_bits-bit integer.  If == -1, then EOF.  This assumes
+ *		that n_bits =< (long)wordsize - 1.
+ * Outputs:
+ * 	Outputs code to the file.
+ * Assumptions:
+ *	Chars are 8 bits long.
+ * Algorithm:
+ * 	Maintain a BITS character long buffer (so that 8 codes will
+ * fit in it exactly).  When the buffer fills up empty it and start over.
+ */
+void
+output(code_int code)
+{
+	int r_off, bits;
+	char *bp;
+
+	r_off = offset;
+	bits = n_bits;
+	bp = buf;
+	if (code >= 0) {
+		/*
+		 * byte/bit numbering on the VAX is simulated by the
+		 * following code
+		 */
+		/*
+		 * Get to the first byte.
+		 */
+		bp += (r_off >> 3);
+		r_off &= 7;
+		/*
+		 * Since code is always >= 8 bits, only need to mask the first
+		 * hunk on the left.
+		 */
+		*bp = (*bp & rmask[r_off]) | (code << r_off) & lmask[r_off];
+		bp++;
+		bits -=  8 - r_off;
+		code >>= 8 - r_off;
+		/* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
+		if ( bits >= 8 ) {
+			*bp++ = code;
+			code >>= 8;
+			bits -= 8;
+		}
+		/* Last bits. */
+		if(bits)
+			*bp = code;
+
+		offset += n_bits;
+		if ( offset == (n_bits << 3) ) {
+			bp = buf;
+			bits = n_bits;
+			bytes_out += bits;
+			do {
+				putchar(*bp++);
+			} while(--bits);
+			offset = 0;
+		}
+
+		/*
+		 * If the next entry is going to be too big for the code size,
+		 * then increase it, if possible.
+		 */
+		if ( free_ent > maxcode || (clear_flg > 0)) {
+			/*
+			* Write the whole buffer, because the input side won't
+			* discover the size increase until after it has read it.
+			*/
+			if ( offset > 0 ) {
+				if( fwrite( buf, 1, n_bits, stdout ) != n_bits)
+					writeerr();
+				bytes_out += n_bits;
+			}
+			offset = 0;
+
+			if ( clear_flg ) {
+				maxcode = MAXCODE (n_bits = INIT_BITS);
+				clear_flg = 0;
+			} else {
+				n_bits++;
+				if ( n_bits == maxbits )
+					maxcode = maxmaxcode;
+				else
+					maxcode = MAXCODE(n_bits);
+			}
+		}
+	} else {
+		/*
+		 * At EOF, write the rest of the buffer.
+		 */
+		if ( offset > 0 )
+			fwrite( buf, 1, (offset + 7) / 8, stdout );
+		bytes_out += (offset + 7) / 8;
+		offset = 0;
+		fflush( stdout );
+		if( ferror( stdout ) )
+			writeerr();
+	}
+}
+
+/*
+ * compress stdin to stdout
+ *
+ * Algorithm:  use open addressing double hashing (no chaining) on the
+ * prefix code / next character combination.  We do a variant of Knuth's
+ * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
+ * secondary probe.  Here, the modular division first probe is gives way
+ * to a faster exclusive-or manipulation.  Also do block compression with
+ * an adaptive reset, whereby the code table is cleared when the compression
+ * ratio decreases, but after the table fills.  The variable-length output
+ * codes are re-sized at this point, and a special CLEAR code is generated
+ * for the decompressor.  Late addition:  construct the table according to
+ * file size for noticeable speed improvement on small files.  Please direct
+ * questions about this implementation to ames!jaw.
+ */
+void
+compress(void)
+{
+	code_int ent, hsize_reg;
+	code_int i;
+	int c, disp, hshift;
+	long fcode;
+
+	if (nomagic == 0) {
+		putchar(magic_header[0]);
+		putchar(magic_header[1]);
+		putchar((char)(maxbits | block_compress));
+		if(ferror(stdout))
+			writeerr();
+	}
+	offset = 0;
+	bytes_out = 3;		/* includes 3-byte header mojo */
+	out_count = 0;
+	clear_flg = 0;
+	ratio = 0;
+	in_count = 1;
+	checkpoint = CHECK_GAP;
+	maxcode = MAXCODE(n_bits = INIT_BITS);
+	free_ent = (block_compress? FIRST: 256);
+
+	ent = getchar ();
+
+	hshift = 0;
+	for (fcode = (long)hsize;  fcode < 65536L; fcode *= 2)
+		hshift++;
+	hshift = 8 - hshift;		/* set hash code range bound */
+
+	hsize_reg = hsize;
+	cl_hash( (count_int) hsize_reg);		/* clear hash table */
+
+	while ((c = getchar()) != EOF) {
+		in_count++;
+		fcode = (long) (((long) c << maxbits) + ent);
+	 	i = ((c << hshift) ^ ent);	/* xor hashing */
+
+		if (Htabof (i) == fcode) {
+			ent = Codetabof(i);
+			continue;
+		} else if ((long)Htabof(i) < 0 )	/* empty slot */
+			goto nomatch;
+	 	disp = hsize_reg - i;	/* secondary hash (after G. Knott) */
+		if (i == 0)
+			disp = 1;
+probe:
+		if ((i -= disp) < 0)
+			i += hsize_reg;
+
+		if (Htabof (i) == fcode) {
+			ent = Codetabof(i);
+			continue;
+		}
+		if ((long)Htabof(i) > 0)
+			goto probe;
+nomatch:
+		output((code_int)ent);
+		out_count++;
+	 	ent = c;
+		if (free_ent < maxmaxcode) {
+	 		Codetabof(i) = free_ent++;	/* code -> hashtable */
+			Htabof(i) = fcode;
+		} else if ((count_int)in_count >= checkpoint && block_compress)
+			cl_block ();
+	}
+	/*
+	* Put out the final code.
+	*/
+	output( (code_int)ent );
+	out_count++;
+	output( (code_int)-1 );
+
+	/*
+	* Print out stats on stderr
+	*/
+	if(zcat_flg == 0 && !quiet) {
+	fprintf( stderr, "Compression: " );
+	prratio( stderr, in_count-bytes_out, in_count );
+	}
+	if(bytes_out > in_count)	/* exit(2) if no savings */
+		exit_stat = 2;
+}
+
+/*
+ * Decompress stdin to stdout.  This routine adapts to the codes in the
+ * file building the "string" table on-the-fly; requiring no table to
+ * be stored in the compressed file.  The tables used herein are shared
+ * with those of the compress() routine.  See the definitions above.
+ */
+void
+decompress(void)
+{
+	int finchar;
+	code_int code, oldcode, incode;
+	uchar *stackp;
+
+	/*
+	* As above, initialize the first 256 entries in the table.
+	*/
+	maxcode = MAXCODE(n_bits = INIT_BITS);
+	for (code = 255; code >= 0; code--) {
+		Tab_prefixof(code) = 0;
+		Tab_suffixof(code) = (uchar)code;
+	}
+	free_ent = (block_compress? FIRST: 256);
+
+	finchar = oldcode = getcode();
+	if(oldcode == -1)		/* EOF already? */
+		return;			/* Get out of here */
+	putchar((char)finchar);		/* first code must be 8 bits = char */
+	if(ferror(stdout))		/* Crash if can't write */
+		writeerr();
+	stackp = De_stack;
+
+	while ((code = getcode()) > -1) {
+		if ((code == CLEAR) && block_compress) {
+			for (code = 255; code >= 0; code--)
+				Tab_prefixof(code) = 0;
+			clear_flg = 1;
+			free_ent = FIRST - 1;
+			if ((code = getcode()) == -1)	/* O, untimely death! */
+				break;
+		}
+		incode = code;
+		/*
+		 * Special case for KwKwK string.
+		 */
+		if (code >= free_ent) {
+			*stackp++ = finchar;
+			code = oldcode;
+		}
+
+		/*
+		 * Generate output characters in reverse order
+		 */
+		while (code >= 256) {
+			*stackp++ = Tab_suffixof(code);
+			code = Tab_prefixof(code);
+		}
+		*stackp++ = finchar = Tab_suffixof(code);
+
+		/*
+		 * And put them out in forward order
+		 */
+		do {
+			putchar(*--stackp);
+		} while (stackp > De_stack);
+
+		/*
+		 * Generate the new entry.
+		 */
+		if ( (code=free_ent) < maxmaxcode ) {
+			Tab_prefixof(code) = (ushort)oldcode;
+			Tab_suffixof(code) = finchar;
+			free_ent = code+1;
+		}
+		/*
+		 * Remember previous code.
+		 */
+		oldcode = incode;
+	}
+	fflush(stdout);
+	if(ferror(stdout))
+		writeerr();
+}
+
+void
 main(int argc, char **argv)
 {
-	int overwrite = 0;	/* Do not overwrite unless given -f flag */
+	int overwrite;
 	char tempname[512];
 	char **filelist, **fileptr;
 	char *cp;
 	struct stat statbuf;
 
+	overwrite = 0;	/* Do not overwrite unless given -f flag */
+
 	if ( (bgnd_flag = signal ( SIGINT, SIG_IGN )) != SIG_IGN ) {
 		signal(SIGINT, onintr);
 		signal(SIGSEGV, oops);
@@ -209,19 +711,9 @@
 		case 'C':
 			block_compress = 0;
 			break;
-#ifdef DEBUG
-		case 'D':
-			debug = 1;
-			break;
 		case 'V':
-			verbose = 1;
 			version();
 			break;
-#else
-		case 'V':
-			version();
-			break;
-#endif
 		case 'b':
 			if (!ARGVAL()) {
 				fprintf(stderr, "Missing maxbits\n");
@@ -328,19 +820,18 @@
 		 */
 		hsize = HSIZE;
 		if (fsize < (1 << 12))
-			hsize = min(5003, HSIZE);
+			hsize = Min(5003, HSIZE);
 		else if (fsize < (1 << 13))
-			hsize = min(9001, HSIZE);
+			hsize = Min(9001, HSIZE);
 		else if (fsize < (1 << 14))
-			hsize = min (18013, HSIZE);
+			hsize = Min (18013, HSIZE);
 		else if (fsize < (1 << 15))
-			hsize = min (35023, HSIZE);
+			hsize = Min (35023, HSIZE);
 		else if (fsize < 47000)
-			hsize = min (50021, HSIZE);
+			hsize = Min (50021, HSIZE);
 
 		/* Generate output filename */
 		strcpy(ofname, *fileptr);
-#ifndef BSD4_2
 		if ((cp=strrchr(ofname,'/')) != NULL)
 			cp++;
 		else
@@ -354,7 +845,6 @@
 				cp);
 			continue;
 		}
-#endif
 		strcat(ofname, ".Z");
 		}
 		/* Check for overwrite of existing file */
@@ -394,17 +884,8 @@
 		/* Actually do the compression/decompression */
 		if (do_decomp == 0)
 			compress();
-#ifndef DEBUG
 		else
 			decompress();
-#else
-		else if (debug == 0)
-			decompress();
-		else
-			printcodes();
-		if (verbose)
-			dump_tab();
-#endif						/* DEBUG */
 		if(zcat_flg == 0) {
 			copystat(*fileptr, ofname);	/* Copy stats */
 			if (exit_stat == 1 || !quiet)
@@ -414,10 +895,6 @@
 	} else {		/* Standard input */
 	if (do_decomp == 0) {
 		compress();
-#ifdef DEBUG
-		if(verbose)
-			dump_tab();
-#endif
 		if(!quiet)
 			putc('\n', stderr);
 	} else {
@@ -440,706 +917,10 @@
 			exit(1);
 		}
 		}
-#ifndef DEBUG
 		decompress();
-#else
-		if (debug == 0)
-			decompress();
-		else
-			printcodes();
-		if (verbose)
-			dump_tab();
-#endif						/* DEBUG */
 	}
 	}
 	exit(exit_stat);
-}
-
-static int offset;
-long in_count = 1;		/* length of input */
-long bytes_out;			/* length of compressed output */
-long out_count = 0;		/* # of codes output (for debugging) */
-
-/*
- * compress stdin to stdout
- *
- * Algorithm:  use open addressing double hashing (no chaining) on the
- * prefix code / next character combination.  We do a variant of Knuth's
- * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
- * secondary probe.  Here, the modular division first probe is gives way
- * to a faster exclusive-or manipulation.  Also do block compression with
- * an adaptive reset, whereby the code table is cleared when the compression
- * ratio decreases, but after the table fills.  The variable-length output
- * codes are re-sized at this point, and a special CLEAR code is generated
- * for the decompressor.  Late addition:  construct the table according to
- * file size for noticeable speed improvement on small files.  Please direct
- * questions about this implementation to ames!jaw.
- */
-void
-compress(void)
-{
-	code_int ent, hsize_reg;
-	code_int i;
-	int c, disp, hshift;
-	long fcode;
-
-	if (nomagic == 0) {
-		putchar(magic_header[0]);
-		putchar(magic_header[1]);
-		putchar((char)(maxbits | block_compress));
-		if(ferror(stdout))
-			writeerr();
-	}
-	offset = 0;
-	bytes_out = 3;		/* includes 3-byte header mojo */
-	out_count = 0;
-	clear_flg = 0;
-	ratio = 0;
-	in_count = 1;
-	checkpoint = CHECK_GAP;
-	maxcode = MAXCODE(n_bits = INIT_BITS);
-	free_ent = (block_compress? FIRST: 256);
-
-	ent = getchar ();
-
-	hshift = 0;
-	for (fcode = (long)hsize;  fcode < 65536L; fcode *= 2)
-		hshift++;
-	hshift = 8 - hshift;		/* set hash code range bound */
-
-	hsize_reg = hsize;
-	cl_hash( (count_int) hsize_reg);		/* clear hash table */
-
-	while ((c = getchar()) != EOF) {
-		in_count++;
-		fcode = (long) (((long) c << maxbits) + ent);
-	 	i = ((c << hshift) ^ ent);	/* xor hashing */
-
-		if (htabof (i) == fcode) {
-			ent = codetabof(i);
-			continue;
-		} else if ((long)htabof(i) < 0 )	/* empty slot */
-			goto nomatch;
-	 	disp = hsize_reg - i;	/* secondary hash (after G. Knott) */
-		if (i == 0)
-			disp = 1;
-probe:
-		if ((i -= disp) < 0)
-			i += hsize_reg;
-
-		if (htabof (i) == fcode) {
-			ent = codetabof(i);
-			continue;
-		}
-		if ((long)htabof(i) > 0)
-			goto probe;
-nomatch:
-		output((code_int)ent);
-		out_count++;
-	 	ent = c;
-		if (free_ent < maxmaxcode) {
-	 		codetabof(i) = free_ent++;	/* code -> hashtable */
-			htabof(i) = fcode;
-		} else if ((count_int)in_count >= checkpoint && block_compress)
-			cl_block ();
-	}
-	/*
-	* Put out the final code.
-	*/
-	output( (code_int)ent );
-	out_count++;
-	output( (code_int)-1 );
-
-	/*
-	* Print out stats on stderr
-	*/
-	if(zcat_flg == 0 && !quiet) {
-#ifdef DEBUG
-	fprintf( stderr,
-		"%ld chars in, %ld codes (%ld bytes) out, compression factor: ",
-		in_count, out_count, bytes_out );
-	prratio( stderr, in_count, bytes_out );
-	fprintf( stderr, "\n");
-	fprintf( stderr, "\tCompression as in compact: " );
-	prratio( stderr, in_count-bytes_out, in_count );
-	fprintf( stderr, "\n");
-	fprintf( stderr, "\tLargest code (of last block) was %d (%d bits)\n",
-		free_ent - 1, n_bits );
-#else /* !DEBUG */
-	fprintf( stderr, "Compression: " );
-	prratio( stderr, in_count-bytes_out, in_count );
-#endif /* DEBUG */
-	}
-	if(bytes_out > in_count)	/* exit(2) if no savings */
-		exit_stat = 2;
-}
-
-/*
- * TAG( output )
- *
- * Output the given code.
- * Inputs:
- * 	code:	A n_bits-bit integer.  If == -1, then EOF.  This assumes
- *		that n_bits =< (long)wordsize - 1.
- * Outputs:
- * 	Outputs code to the file.
- * Assumptions:
- *	Chars are 8 bits long.
- * Algorithm:
- * 	Maintain a BITS character long buffer (so that 8 codes will
- * fit in it exactly).  When the buffer fills up empty it and start over.
- */
-
-static char buf[BITS];
-
-uchar lmask[9] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
-uchar rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
-
-void
-output(code_int code)
-{
-#ifdef DEBUG
-	static int col = 0;
-#endif
-	int r_off = offset, bits= n_bits;
-	char *bp = buf;
-
-#ifdef DEBUG
-	if (verbose)
-		fprintf(stderr, "%5d%c", code,
-			(col+=6) >= 74? (col = 0, '\n'): ' ');
-#endif
-	if (code >= 0) {
-		/*
-		 * byte/bit numbering on the VAX is simulated by the
-		 * following code
-		 */
-		/*
-		 * Get to the first byte.
-		 */
-		bp += (r_off >> 3);
-		r_off &= 7;
-		/*
-		 * Since code is always >= 8 bits, only need to mask the first
-		 * hunk on the left.
-		 */
-		*bp = (*bp & rmask[r_off]) | (code << r_off) & lmask[r_off];
-		bp++;
-		bits -=  8 - r_off;
-		code >>= 8 - r_off;
-		/* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
-		if ( bits >= 8 ) {
-			*bp++ = code;
-			code >>= 8;
-			bits -= 8;
-		}
-		/* Last bits. */
-		if(bits)
-			*bp = code;
-
-		offset += n_bits;
-		if ( offset == (n_bits << 3) ) {
-			bp = buf;
-			bits = n_bits;
-			bytes_out += bits;
-			do {
-				putchar(*bp++);
-			} while(--bits);
-			offset = 0;
-		}
-
-		/*
-		 * If the next entry is going to be too big for the code size,
-		 * then increase it, if possible.
-		 */
-		if ( free_ent > maxcode || (clear_flg > 0)) {
-			/*
-			* Write the whole buffer, because the input side won't
-			* discover the size increase until after it has read it.
-			*/
-			if ( offset > 0 ) {
-				if( fwrite( buf, 1, n_bits, stdout ) != n_bits)
-					writeerr();
-				bytes_out += n_bits;
-			}
-			offset = 0;
-
-			if ( clear_flg ) {
-				maxcode = MAXCODE (n_bits = INIT_BITS);
-				clear_flg = 0;
-			} else {
-				n_bits++;
-				if ( n_bits == maxbits )
-					maxcode = maxmaxcode;
-				else
-					maxcode = MAXCODE(n_bits);
-			}
-#ifdef DEBUG
-			if ( debug ) {
-				fprintf(stderr,
-					"\nChange to %d bits\n", n_bits);
-				col = 0;
-			}
-#endif
-		}
-	} else {
-		/*
-		 * At EOF, write the rest of the buffer.
-		 */
-		if ( offset > 0 )
-			fwrite( buf, 1, (offset + 7) / 8, stdout );
-		bytes_out += (offset + 7) / 8;
-		offset = 0;
-		fflush( stdout );
-#ifdef DEBUG
-		if ( verbose )
-			fprintf( stderr, "\n" );
-#endif
-		if( ferror( stdout ) )
-			writeerr();
-	}
-}
-
-/*
- * Decompress stdin to stdout.  This routine adapts to the codes in the
- * file building the "string" table on-the-fly; requiring no table to
- * be stored in the compressed file.  The tables used herein are shared
- * with those of the compress() routine.  See the definitions above.
- */
-void
-decompress(void)
-{
-	int finchar;
-	code_int code, oldcode, incode;
-	uchar *stackp;
-
-	/*
-	* As above, initialize the first 256 entries in the table.
-	*/
-	maxcode = MAXCODE(n_bits = INIT_BITS);
-	for (code = 255; code >= 0; code--) {
-		tab_prefixof(code) = 0;
-		tab_suffixof(code) = (uchar)code;
-	}
-	free_ent = (block_compress? FIRST: 256);
-
-	finchar = oldcode = getcode();
-	if(oldcode == -1)		/* EOF already? */
-		return;			/* Get out of here */
-	putchar((char)finchar);		/* first code must be 8 bits = char */
-	if(ferror(stdout))		/* Crash if can't write */
-		writeerr();
-	stackp = de_stack;
-
-	while ((code = getcode()) > -1) {
-		if ((code == CLEAR) && block_compress) {
-			for (code = 255; code >= 0; code--)
-				tab_prefixof(code) = 0;
-			clear_flg = 1;
-			free_ent = FIRST - 1;
-			if ((code = getcode()) == -1)	/* O, untimely death! */
-				break;
-		}
-		incode = code;
-		/*
-		 * Special case for KwKwK string.
-		 */
-		if (code >= free_ent) {
-			*stackp++ = finchar;
-			code = oldcode;
-		}
-
-		/*
-		 * Generate output characters in reverse order
-		 */
-		while (code >= 256) {
-			*stackp++ = tab_suffixof(code);
-			code = tab_prefixof(code);
-		}
-		*stackp++ = finchar = tab_suffixof(code);
-
-		/*
-		 * And put them out in forward order
-		 */
-		do {
-			putchar(*--stackp);
-		} while (stackp > de_stack);
-
-		/*
-		 * Generate the new entry.
-		 */
-		if ( (code=free_ent) < maxmaxcode ) {
-			tab_prefixof(code) = (ushort)oldcode;
-			tab_suffixof(code) = finchar;
-			free_ent = code+1;
-		}
-		/*
-		 * Remember previous code.
-		 */
-		oldcode = incode;
-	}
-	fflush(stdout);
-	if(ferror(stdout))
-		writeerr();
-}
-
-/*
- * TAG( getcode )
- *
- * Read one code from the standard input.  If EOF, return -1.
- * Inputs:
- * 	stdin
- * Outputs:
- * 	code or -1 is returned.
- */
-code_int
-getcode(void)
-{
-	int r_off, bits;
-	code_int code;
-	static int offset = 0, size = 0;
-	static uchar buf[BITS];
-	uchar *bp = buf;
-
-	if ( clear_flg > 0 || offset >= size || free_ent > maxcode ) {
-		/*
-		 * If the next entry will be too big for the current code
-		 * size, then we must increase the size.  This implies reading
-		 * a new buffer full, too.
-		 */
-		if ( free_ent > maxcode ) {
-			n_bits++;
-			if ( n_bits == maxbits )
-				maxcode = maxmaxcode; /* won't get any bigger now */
-			else
-				maxcode = MAXCODE(n_bits);
-		}
-		if ( clear_flg > 0) {
-			maxcode = MAXCODE(n_bits = INIT_BITS);
-			clear_flg = 0;
-		}
-		size = fread(buf, 1, n_bits, stdin);
-		if (size <= 0)
-			return -1;			/* end of file */
-		offset = 0;
-		/* Round size down to integral number of codes */
-		size = (size << 3) - (n_bits - 1);
-	}
-	r_off = offset;
-	bits = n_bits;
-	/*
-	 * Get to the first byte.
-	 */
-	bp += (r_off >> 3);
-	r_off &= 7;
-	/* Get first part (low order bits) */
-	code = (*bp++ >> r_off);
-	bits -= (8 - r_off);
-	r_off = 8 - r_off;		/* now, offset into code word */
-	/* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
-	if (bits >= 8) {
-		code |= *bp++ << r_off;
-		r_off += 8;
-		bits -= 8;
-	}
-	/* high order bits. */
-	code |= (*bp & rmask[bits]) << r_off;
-	offset += n_bits;
-	return code;
-}
-
-#ifdef DEBUG
-void
-printcodes(void)
-{
-	/*
-	* Just print out codes from input file.  For debugging.
-	*/
-	code_int code;
-	int col = 0, bits;
-
-	bits = n_bits = INIT_BITS;
-	maxcode = MAXCODE(n_bits);
-	free_ent = ((block_compress) ? FIRST : 256 );
-	while ( ( code = getcode() ) >= 0 ) {
-	if ( (code == CLEAR) && block_compress ) {
-			free_ent = FIRST - 1;
-			clear_flg = 1;
-	}
-	else if ( free_ent < maxmaxcode )
-		free_ent++;
-	if ( bits != n_bits ) {
-		fprintf(stderr, "\nChange to %d bits\n", n_bits );
-		bits = n_bits;
-		col = 0;
-	}
-	fprintf(stderr, "%5d%c", code, (col+=6) >= 74 ? (col = 0, '\n') : ' ' );
-	}
-	putc( '\n', stderr );
-	exit( 0 );
-}
-
-code_int sorttab[1<<BITS];	/* sorted pointers into htab */
-
-#define STACK_SIZE	15000
-
-dump_tab()	/* dump string table */
-{
-	int i, first, c, ent;
-	int stack_top = STACK_SIZE;
-
-	if(do_decomp == 0) {	/* compressing */
-	int flag = 1;
-
-	for(i=0; i<hsize; i++) {	/* build sort pointers */
-		if((long)htabof(i) >= 0) {
-			sorttab[codetabof(i)] = i;
-		}
-	}
-	first = block_compress ? FIRST : 256;
-	for(i = first; i < free_ent; i++) {
-		fprintf(stderr, "%5d: \"", i);
-		de_stack[--stack_top] = '\n';
-		de_stack[--stack_top] = '"';
-		stack_top = in_stack((htabof(sorttab[i])>>maxbits)&0xff,
-	stack_top);
-		for(ent=htabof(sorttab[i]) & ((1<<maxbits)-1);
-			ent > 256;
-			ent=htabof(sorttab[ent]) & ((1<<maxbits)-1)) {
-			stack_top = in_stack(htabof(sorttab[ent]) >> maxbits,
-						stack_top);
-		}
-		stack_top = in_stack(ent, stack_top);
-		fwrite( &de_stack[stack_top], 1, STACK_SIZE-stack_top, stderr);
-			stack_top = STACK_SIZE;
-	}
-	} else if(!debug) {	/* decompressing */
-
-	for ( i = 0; i < free_ent; i++ ) {
-		ent = i;
-		c = tab_suffixof(ent);
-		if ( isascii(c) && isprint(c) )
-		fprintf( stderr, "%5d: %5d/'%c'  \"",
-				ent, tab_prefixof(ent), c );
-		else
-		fprintf( stderr, "%5d: %5d/\\%03o \"",
-				ent, tab_prefixof(ent), c );
-		de_stack[--stack_top] = '\n';
-		de_stack[--stack_top] = '"';
-		for ( ; ent != NULL;
-			ent = (ent >= FIRST ? tab_prefixof(ent) : NULL) ) {
-		stack_top = in_stack(tab_suffixof(ent), stack_top);
-		}
-		fwrite( &de_stack[stack_top], 1, STACK_SIZE - stack_top, stderr );
-		stack_top = STACK_SIZE;
-	}
-	}
-}
-
-int
-in_stack(int c, int stack_top)
-{
-	if ( (isascii(c) && isprint(c) && c != '\\') || c == ' ' ) {
-		de_stack[--stack_top] = c;
-	} else {
-		switch( c ) {
-		case '\n': de_stack[--stack_top] = 'n'; break;
-		case '\t': de_stack[--stack_top] = 't'; break;
-		case '\b': de_stack[--stack_top] = 'b'; break;
-		case '\f': de_stack[--stack_top] = 'f'; break;
-		case '\r': de_stack[--stack_top] = 'r'; break;
-		case '\\': de_stack[--stack_top] = '\\'; break;
-		default:
-	 	de_stack[--stack_top] = '0' + c % 8;
-	 	de_stack[--stack_top] = '0' + (c / 8) % 8;
-	 	de_stack[--stack_top] = '0' + c / 64;
-	 	break;
-		}
-		de_stack[--stack_top] = '\\';
-	}
-	return stack_top;
-}
-#endif /* DEBUG */
-
-void
-writeerr(void)
-{
-	perror(ofname);
-	unlink(ofname);
-	exit(1);
-}
-
-void
-copystat(char *ifname, char *ofname)
-{
-	int mode;
-	time_t timep[2];
-	struct stat statbuf;
-
-	fclose(stdout);
-	if (stat(ifname, &statbuf)) {		/* Get stat on input file */
-		perror(ifname);
-		return;
-	}
-	if (!S_ISREG(statbuf.st_mode)) {
-		if (quiet)
-			fprintf(stderr, "%s: ", ifname);
-		fprintf(stderr, " -- not a regular file: unchanged");
-		exit_stat = 1;
-	} else if (exit_stat == 2 && !force) {
-		/* No compression: remove file.Z */
-		if (!quiet)
-			fprintf(stderr, " -- file unchanged");
-	} else {			/* Successful Compression */
-		exit_stat = 0;
-		mode = statbuf.st_mode & 0777;
-		if (chmod(ofname, mode))		/* Copy modes */
-			perror(ofname);
-		/* Copy ownership */
-		chown(ofname, statbuf.st_uid, statbuf.st_gid);
-		timep[0] = statbuf.st_atime;
-		timep[1] = statbuf.st_mtime;
-		/* Update last accessed and modified times */
-		utime(ofname, timep);
-//		if (unlink(ifname))	/* Remove input file */
-//			perror(ifname);
-		return;			/* success */
-	}
-
-	/* Unsuccessful return -- one of the tests failed */
-	if (unlink(ofname))
-		perror(ofname);
-}
-
-/*
- * This routine returns 1 if we are running in the foreground and stderr
- * is a tty.
- */
-int
-foreground(void)
-{
-	if(bgnd_flag)			/* background? */
-		return 0;
-	else				/* foreground */
-		return isatty(2);	/* and stderr is a tty */
-}
-
-void
-onintr(int)
-{
-	unlink(ofname);
-	exit(1);
-}
-
-void
-oops(int)		/* wild pointer -- assume bad input */
-{
-	if (do_decomp == 1)
-		fprintf(stderr, "uncompress: corrupt input\n");
-	unlink(ofname);
-	exit(1);
-}
-
-void
-cl_block (void)		/* table clear for block compress */
-{
-	long rat;
-
-	checkpoint = in_count + CHECK_GAP;
-#ifdef DEBUG
-	if ( debug ) {
-		fprintf ( stderr, "count: %ld, ratio: ", in_count );
-		prratio ( stderr, in_count, bytes_out );
-		fprintf ( stderr, "\n");
-	}
-#endif /* DEBUG */
-
-	if (in_count > 0x007fffff) {	/* shift will overflow */
-		rat = bytes_out >> 8;
-		if (rat == 0)		/* Don't divide by zero */
-			rat = 0x7fffffff;
-		else
-			rat = in_count / rat;
-	} else
-		rat = (in_count << 8) / bytes_out;	/* 8 fractional bits */
-	if (rat > ratio)
-		ratio = rat;
-	else {
-		ratio = 0;
-#ifdef DEBUG
-		if (verbose)
-			dump_tab();	/* dump string table */
-#endif
-		cl_hash((count_int)hsize);
-		free_ent = FIRST;
-		clear_flg = 1;
-		output((code_int)CLEAR);
-#ifdef DEBUG
-		if (debug)
-			fprintf(stderr, "clear\n");
-#endif /* DEBUG */
-	}
-}
-
-void
-cl_hash(count_int hsize)		/* reset code table */
-{
-	count_int *htab_p = htab+hsize;
-	long i;
-	long m1 = -1;
-
-	i = hsize - 16;
- 	do {				/* might use Sys V memset(3) here */
-		*(htab_p-16) = m1;
-		*(htab_p-15) = m1;
-		*(htab_p-14) = m1;
-		*(htab_p-13) = m1;
-		*(htab_p-12) = m1;
-		*(htab_p-11) = m1;
-		*(htab_p-10) = m1;
-		*(htab_p-9) = m1;
-		*(htab_p-8) = m1;
-		*(htab_p-7) = m1;
-		*(htab_p-6) = m1;
-		*(htab_p-5) = m1;
-		*(htab_p-4) = m1;
-		*(htab_p-3) = m1;
-		*(htab_p-2) = m1;
-		*(htab_p-1) = m1;
-		htab_p -= 16;
-	} while ((i -= 16) >= 0);
-	for ( i += 16; i > 0; i-- )
-		*--htab_p = m1;
-}
-
-void
-prratio(FILE *stream, long num, long den)
-{
-	int q;				/* Doesn't need to be long */
-
-	if(num > 214748L)		/* 2147483647/10000 */
-		q = num / (den / 10000L);
-	else
-		q = 10000L * num / den;	/* Long calculations, though */
-	if (q < 0) {
-		putc('-', stream);
-		q = -q;
-	}
-	fprintf(stream, "%d.%02d%%", q / 100, q % 100);
-}
-
-void
-version(void)
-{
-	fprintf(stderr, "%s\n", rcs_ident);
-	fprintf(stderr, "Options: ");
-#ifdef DEBUG
-	fprintf(stderr, "DEBUG, ");
-#endif
-#ifdef BSD4_2
-	fprintf(stderr, "BSD4_2, ");
-#endif
-	fprintf(stderr, "BITS = %d\n", BITS);
 }
 
 /*

</pre>
</p>]]></description></item>
<item>
<guid isPermaLink="true">http://okturing.com:80/?id=21902</guid>
<pubDate>Fri, 11 Sep 2026 19:04:34 -0400</pubDate>
<title>OK, turing. 21902</title>
<link>http://okturing.com:80/?id=21902</link>
<description><![CDATA[
<pre>
diff d683e5c0cf8fcad8fdf21a550453eb9e4b17e8fb uncommitted
--- a/sys/src/cmd/sha1sum.c
+++ b/sys/src/cmd/sha1sum.c
@@ -1,22 +1,20 @@
 /*
- * sha1sum - compute SHA1 or SHA2 digest
+ * sha1sum - compute SHA1, SHA2 or SHA3 digest
  */
 #include <u.h>
 #include <libc.h>
 #include <libsec.h>
 
-#pragma	varargck	type	"M"	uchar*
-
 static char exitstr[ERRMAX];
 
-typedef struct Sha2 Sha2;
-struct Sha2 {
+typedef struct Sha Sha;
+struct Sha {
 	int	bits;
 	int	dlen;
-	DigestState* (*func)(uchar *, ulong, uchar *, DigestState *);
+	DigestState* (*f)(uchar *, ulong, uchar *, DigestState *);
 };
 
-static Sha2 sha2s[] = {
+static Sha sha2s[] = {
 	224,	SHA2_224dlen,	sha2_224,
 	256,	SHA2_256dlen,	sha2_256,
 	384,	SHA2_384dlen,	sha2_384,
@@ -23,21 +21,18 @@
 	512,	SHA2_512dlen,	sha2_512,
 };
 
-static DigestState* (*shafunc)(uchar *, ulong, uchar *, DigestState *);
-static int shadlen;
+static Sha sha3s[] = {
+	224,	SHA3_224dlen,	sha3_224,
+	256,	SHA3_256dlen,	sha3_256,
+	384,	SHA3_384dlen,	sha3_384,
+	512,	SHA3_512dlen,	sha3_512,
+};
 
-static int
-digestfmt(Fmt *fmt)
-{
-	char buf[SHA2_512dlen*2 + 1];
-	uchar *p;
-	int i;
+static Sha sha1s[] = {
+	128,	SHA1dlen,	sha1,
+};
 
-	p = va_arg(fmt->args, uchar*);
-	for(i = 0; i < shadlen; i++)
-		sprint(buf + 2*i, "%.2ux", p[i]);
-	return fmtstrcpy(fmt, buf);
-}
+Sha *hash = &sha1s[0];
 
 static void
 sum(int fd, char *name)
@@ -46,21 +41,32 @@
 	uchar buf[IOUNIT], digest[SHA2_512dlen];
 	DigestState *s;
 
-	s = (*shafunc)(nil, 0, nil, nil);
+	s = hash->f(nil, 0, nil, nil);
 	while((n = read(fd, buf, sizeof buf)) > 0)
-		(*shafunc)(buf, n, nil, s);
+		hash->f(buf, n, nil, s);
 	if(n < 0){
 		snprint(exitstr, sizeof(exitstr), "reading %s: %r\n", name? name: "stdin");
 		fprint(2, "%s", exitstr);
 		return;
 	}
-	(*shafunc)(nil, 0, digest, s);
+	hash->f(nil, 0, digest, s);
 	if(name == nil)
-		print("%M\n", digest);
+		print("%.*lH\n", hash->dlen, digest);
 	else
-		print("%M\t%s\n", digest, name);
+		print("%.*lH\t%s\n", hash->dlen, digest, name);
 }
 
+static Sha*
+pick(Sha *from, int n, int bits)
+{
+	Sha *s;
+
+	for(s = from; s < from+n; s++)
+		if(s->bits == bits)
+			return s;
+	return nil;
+}
+
 static void
 usage(void)
 {
@@ -71,27 +77,20 @@
 void
 main(int argc, char *argv[])
 {
-	int i, fd, bits;
-	Sha2 *sha;
+	int i, fd;
 
-	shafunc = sha1;
-	shadlen = SHA1dlen;
 	ARGBEGIN{
 	case '2':
-		bits = atoi(EARGF(usage()));
-		for (sha = sha2s; sha < sha2s + nelem(sha2s); sha++)
-			if (sha->bits == bits)
-				break;
-		if (sha >= sha2s + nelem(sha2s))
-			sysfatal("unknown number of sha2 bits: %d", bits);
-		shafunc = sha->func;
-		shadlen = sha->dlen;
+		hash = pick(sha2s, nelem(sha2s), atoi(EARGF(usage())));
 		break;
+	case '3':
+		hash = pick(sha3s, nelem(sha3s), atoi(EARGF(usage())));
+		break;
 	default:
 		usage();
 	}ARGEND
 
-	fmtinstall('M', digestfmt);
+	fmtinstall('H', encodefmt);
 
 	if(argc == 0)
 		sum(0, nil);

</pre>
</p>]]></description></item>
<item>
<guid isPermaLink="true">http://okturing.com:80/?id=21901</guid>
<pubDate>Fri, 11 Sep 2026 18:56:40 -0400</pubDate>
<title>OK, turing. 21901</title>
<link>http://okturing.com:80/?id=21901</link>
<description><![CDATA[
<pre>
diff d683e5c0cf8fcad8fdf21a550453eb9e4b17e8fb uncommitted
--- a/lib/bullshit
+++ b/lib/bullshit
@@ -83,11 +83,13 @@
 extensible ^
 compliant ^
 scale-out ^
+vibe-coded ^
 session |
 content-driven |
 high-performance |
 general-purpose |
 out-scaling |
+human-in-the-loop |
 generic ^
 mobile ^
 responsive ^
@@ -116,6 +118,7 @@
 virtual ^
 shared ^
 stable ^
+agentic ^
 SQL *
 JSON *
 XML *
@@ -131,6 +134,7 @@
 SSL *
 HTTP *
 TOR *
+MCP *
 ActivityPub *
 layer $
 element |

</pre>
</p>]]></description></item>
<item>
<guid isPermaLink="true">http://okturing.com:80/?id=21900</guid>
<pubDate>Fri, 11 Sep 2026 18:14:07 -0400</pubDate>
<title>OK, turing. 21900</title>
<link>http://okturing.com:80/?id=21900</link>
<description><![CDATA[
<pre>
% mk -s clean app/blink/stm32l4.bin app/blink/t.out
rm -f app/blink/[t].out app/blink/*.[t] app/blink/stm32l4.bin test/*.[t] \
	stm32l4/lib/*.a \
	libc/port/*.[t] libc/stm32l4/*.[t]
stm32l4/lib/libc.a doesn't exist: assuming it will be an archive
5a -t -o libc/stm32l4/l.t libc/stm32l4/l.s
tc -Iinclude -Istm32l4/include -o libc/port/init.t libc/port/init.c
5a -t -o libc/stm32l4/halt.t libc/stm32l4/halt.s
tc -Iinclude -Istm32l4/include -o libc/stm32l4/sleep.t libc/stm32l4/sleep.c
tc -Iinclude -Istm32l4/include -o libc/stm32l4/sys.t libc/stm32l4/sys.c
tc -Iinclude -Istm32l4/include -o libc/stm32l4/isr.t libc/stm32l4/isr.c
tc -Iinclude -Istm32l4/include -o app/blink/blink.t app/blink/blink.c
ar crv stm32l4/lib/libc.a `{membername $prereq}
a - libc/stm32l4/l.t
a - libc/port/init.t
a - libc/stm32l4/halt.t
a - libc/stm32l4/sleep.t
a - libc/stm32l4/sys.t
a - libc/stm32l4/isr.t
tl -T0x08000000 -R0 -D0x10000000 -a -H0 -o app/blink/stm32l4.bin stm32l4/lib/libc.a app/blink/blink.t | awk '$1 >= "08000400"'
main: undefined external: STK in main
main: undefined external: RCC in main
main: undefined external: GPIOB in main

</pre>
</p>]]></description></item>
<item>
<guid isPermaLink="true">http://okturing.com:80/?id=21897</guid>
<pubDate>Fri, 11 Sep 2026 14:46:42 -0400</pubDate>
<title>OK, turing. 21897</title>
<link>http://okturing.com:80/?id=21897</link>
<description><![CDATA[
<pre>
#include <u.h>
#include <libc.h>

#include "fs.h"

u64int /* this returns a byte position! */
getdentry(u64int dirblk, u64int size, u64int block)
{
	u64int nblks, blk, pos;
	char buf[BLKSZ];
	char target[BLOCKSIZ+1];
	char field[STRSIZ+1];

	seprint(target, target + sizeof(target), "%ulld", block);
	nblks = size / BLKSZ + (size % BLKSZ > 0);

	for(blk = dirblk; blk < dirblk + nblks; ++blk) {
		if(blkread(blk, buf) < 0) {
			werrstr("blkread: %r");
			return 0;
		}

		for(pos = 0; pos + DENTRYSIZ <= BLKSZ; pos += DENTRYSIZ) {
			if(buf[pos] == 'd' || buf[pos] == '#')
				continue;

#ifdef DEFENSIVE
			if(buf[pos] != '+') {
				werrstr("block %ulld: bad status '%c' at entry %ulld",
				blk, buf[pos], (blk - dirblk) * (BLKSZ/DENTRYSIZ) + pos/DENTRYSIZ);
				return 0;
			}
#endif

			getfield(buf + pos, BLOCK, BLOCKSIZ, field);
			if(strtoull(field, nil, 10) == block) {
				return blk * BLKSZ + pos;
			}
		}
	}

	return 0; /* not found */
}

void
getfield(char *buf, int offset, int size, char *out)
{
	int i;

	for(i = 0; i < size; ++i)
		out[i] = buf[offset + i];
	out[size] = '\0';

	for(i = size - 1; i >= 0 && out[i] == ' '; --i)
		out[i] = '\0';
}

void
writefield(char *buf, int offset, int size, char *in)
{
	int i;

	for(i = 0; in[i] != '\0'; ++i)
		buf[offset + i] = in[i];

	for(; i < size; ++i)
		buf[offset + i] = ' ';
}

static int
isleap(u32int year)
{
	return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}

static u64int
iso2unix(char *buf)
{
#ifdef DEFENSIVE
	if(buf[4] != '-'
	|| buf[7] != '-'
	|| buf[10] != 'T'
	|| buf[13] != ':'
	|| buf[16] != ':'
	|| buf[19] != 'Z') {
		werrstr("wrong time format");
		return 0;
	}
#endif

	u32int y, m, d, i;
	u64int days = 0;

	y = strtoul(buf, nil, 10);
	m = strtoul(buf + 5, nil, 10);
	d = strtoul(buf + 8, nil, 10);

	for(i = 1970; i < y; ++i)
		days += 365 + isleap(i);

	int mdays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	if(isleap(y))
		mdays[1] = 29;

	for(i = 0; i < m - 1; ++i)
		days += mdays[i];

	days += d - 1;

	return days * 86400
	+ strtoul(buf + 11, nil, 10) * 3600
	+ strtoul(buf + 14, nil, 10) * 60
	+ strtoul(buf + 17, nil, 10);
}

static char *
unix2iso(char *buf, u64int t)
{
	u32int y = 1970, m, d, h, min, s;
	u64int days = t / 86400;
	u32int secs = t % 86400;
	int mdays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

	while(days >= 365 + isleap(y)) {
		days -= 365 + isleap(y);
		++y;
	}

	if(isleap(y))
		mdays[1] = 29;

	m = 0;
	while(m < 12 && days >= mdays[m]) {
		days -= mdays[m];
		++m;
	}

	d = days + 1;
	h = secs / 3600;
	min = (secs % 3600) / 60;
	s = secs % 60;

	snprint(buf, 20, "%04ud-%02ud-%02udT%02ud:%02ud:%02udZ", y, m+1, d, h, min, s);
	return buf;
}

#ifdef DEFENSIVE
static ulong
rwx2num(char *buf)
{
	ulong p = 0;
	
	if(buf[0] == 'r')
		p |= (1 << 8);
	else if(buf[0] != '-')
		goto err;
	if(buf[1] == 'w')
		p |= (1 << 7);
	else if(buf[1] != '-')
		goto err;
	if(buf[2] == 'x')
		p |= (1 << 6);
	else if(buf[2] != 'x')
		goto err;
	
	if(buf[3] == 'r')
		p |= (1 << 5);
	else if(buf[3] != '-')
		goto err;
	if(buf[4] == 'w')
		p |= (1 << 4);
	else if(buf[4] != '-')
		goto err;
	if(buf[5] == 'x')
		p |= (1 << 3);
	else if(buf[5] != '-')
		goto err;
	
	if(buf[6] == 'r')
		p |= (1 << 2);
	else if(buf[6] != '-')
		goto err;
	if(buf[7] == 'w')
		p |= (1 << 1);
	else if(buf[7] != '-')
		goto err;
	if(buf[8] == 'x')
		p |= (1 << 0);
	else if(buf[8] != '-')
		goto err;
	
	return p;

err:
	werrstr("incorrect permissions format");
	return 0;
}
#endif
#ifndef DEFENSIVE
static ulong
rwx2num(char *buf)
{
	ulong p = 0;
	
	if(buf[0] == 'r')
		p |= (1 << 8);
	if(buf[1] == 'w')
		p |= (1 << 7);
	if(buf[2] == 'x')
		p |= (1 << 6);

	if(buf[3] == 'r')
		p |= (1 << 5);
	if(buf[4] == 'w')
		p |= (1 << 4);
	if(buf[5] == 'x')
		p |= (1 << 3);

	if(buf[6] == 'r')
		p |= (1 << 2);
	if(buf[7] == 'w')
		p |= (1 << 1);
	if(buf[8] == 'x')
		p |= (1 << 0);

	
	return p;
}
#endif

static char *
num2rwx(char *buf, ulong mode)
{
	buf[0] = (mode & (1 << 8)) ? 'r' : '-';
	buf[1] = (mode & (1 << 7)) ? 'w' : '-';
	buf[2] = (mode & (1 << 6)) ? 'x' : '-';
	
	buf[3] = (mode & (1 << 5)) ? 'r' : '-';
	buf[4] = (mode & (1 << 4)) ? 'w' : '-';
	buf[5] = (mode & (1 << 3)) ? 'x' : '-';
	
	buf[6] = (mode & (1 << 2)) ? 'r' : '-';
	buf[7] = (mode & (1 << 1)) ? 'w' : '-';
	buf[8] = (mode & (1 << 0)) ? 'x' : '-';
	
	buf[9] = '\0';
	
	return buf;
}
 
Dir *
fsstat(u64int dentrypos)
{
	u64int pos; /* to avoid a conversion */
	u64int blk;
	char buf[BLKSZ];
	char field[STRSIZ+1];

	pos = dentrypos % BLKSZ;
	blk = dentrypos / BLKSZ + (pos > 0);

	if(blkread(blk, buf) < 0) {
		werrstr("blkread: %r");
		return nil;
	}

	Dir *out = calloc(1, sizeof(Dir));
	if(out == nil) {
		werrstr("calloc: %r");
		return nil;
	}

	/* Qid */
	getfield(buf + pos, BLOCK, BLOCKSIZ, field);
	out->qid.path = strtoull(field, nil, 10);

	/* Type */ /* add fragmentation support here */
	getfield(buf + pos, TYPE, TYPESIZ, field);
	if(strcmp(field, " DIR") == 0) {
		out->qid.type = QTDIR;
		out->mode = DMDIR;
	} else if(strcmp(field, " APPD") == 0) {
		out->qid.type = QTAPPEND;
		out->mode = DMAPPEND;
	} else if(strcmp(field, " EXCL") == 0) {
		out->qid.type = QTEXCL;
		out->mode = DMEXCL;
	} else {
		out->qid.type = QTFILE;
		out->mode = 0;
	}

	/* Perms */
	getfield(buf + pos, PERMS, PERMSSIZ, field);
	out->mode |= rwx2num(field);

	/* Name */
	getfield(buf + pos, NAME, NAMESIZ, field);
	out->name = strdup(field);
	if(out->name == nil)
		goto nomem;

	/* Size */
	getfield(buf + pos, SIZE, SIZESIZ, field);
	out->length = strtoll(field, nil, 10);

	/* UID */
	getfield(buf + pos, UID, UIDSIZ, field);
	out->uid = strdup(field);
	if(out->uid == nil)
		goto nomem;

	/* GID */
	getfield(buf + pos, GID, GIDSIZ, field);
	out->gid = strdup(field);
	if(out->gid == nil)
		goto nomem;

	/* MUID */
	getfield(buf + pos, MUID, MUIDSIZ, field);
	out->muid = strdup(field);
	if(out->muid == nil)
		goto nomem;

	/* Times */
	getfield(buf + pos, MTIME, MTIMESIZ, field);
	out->mtime = iso2unix(field);
#ifdef DEFENSIVE
	if(out->mtime == 0) {
		werrstr("iso2unix: %r");
		goto err;
	}
#endif

	getfield(buf + pos, ATIME, ATIMESIZ, field);
	out->atime = iso2unix(field);
#ifdef DEFENSIVE
	if(out->atime == 0) {
		werrstr("iso2unix: %r");
		goto err;
	}
#endif

	return out;

nomem:
	werrstr("malloc: %r");
err:
	free(out->name);
	free(out->uid);
	free(out->gid);
	free(out->muid);
	free(out);
	return nil;
}

 
u64int
dir1up(u64int dirblk,    u64int dirsize,
       Qid *parent,      u64int parentsize)
{
	u64int parentblk = parent->path;
	u64int parentblks = parentsize / BLKSZ + (parentsize % BLKSZ > 0);
#ifdef DEFENSIVE
	if(dirblk == super.rootblk || parentblk == SUPERBLK) {
		werrstr("Cannot extend root directory");
		return 0;
		/* stub - you should actually extend here */
	}
#endif

	u64int dirnblks = dirsize / BLKSZ + (dirsize % BLKSZ > 0);

	u64int nextblk = dirblk + dirnblks;
	if(nextblk < super.nblocks && !bused(nextblk, nextblk)) {
		if(balloc(nextblk, nextblk) < 0) {
			werrstr("balloc: %r");
			return 0;
		}
	
	
		return dirblk;
	}





	u64int newblk = bfindfree(dirnblks + 1, dirblk);
	if(newblk == 0) {
		werrstr("no space for %ulld contiguous blocks", dirnblks + 1);
		return 0;
	}

	if(balloc(newblk, newblk + dirnblks) < 0) {
		werrstr("balloc: %r");
		return 0;
	}

	char buf[BLKSZ];
	for(u64int i = 0; i < dirnblks; i++) {
		if(blkcopy(dirblk + i, newblk + i, buf) < 0) {
			werrstr("blkcopy: %r");
			if(bfree(newblk, newblk + dirnblks) < 0)
				werrstr("blkcopy and bfree: %r");
			return 0;
		}
	}

	u64int pos = getdentry(parentblk, parentblks, dirblk);
	if(pos == 0) {
		werrstr("getdentry: %r");
		return 0;
	}
	u64int dblk = pos / BLKSZ;
	pos = pos % BLKSZ;
	if(blkread(dblk, buf) < 0) {
		werrstr("blkread: %r");
		return 0;
	}
	char field[BLOCKSIZ + 1];
	seprint(field, field + sizeof(field), "%ulld", newblk);
	writefield(buf + pos % BLKSZ, BLOCK, BLOCKSIZ, field);
	if(blkwrite(dblk, buf) < 0) {
		werrstr("blkwrite: %r");
		return 0;
	}
	INCR_VERS(parent->vers);

	if(bfree(dirblk, dirblk + dirnblks - 1) < 0) {
		werrstr("bfree: %r");
		return 0;
	}

	return newblk;
}

int //add a root case
initdentry(Qid *dir,    u64int dirsize,
           Qid *parent, u64int parentsize,
           Dir *file)
{
	u64int dirblk = dir->path, parentblk = parent->path;
	u64int blk, pos;
	u64int nblks = dirsize / BLKSZ + (dirsize % BLKSZ > 0);
	char buf[BLKSZ], field[STRSIZ+1];

	for(blk = dirblk; blk < dirblk + nblks; ++blk) {
		if(blkread(blk, buf) < 0) {
			werrstr("blkread: %r");
			return -1;
		}

		for(pos = 0; pos + DENTRYSIZ <= BLKSZ; pos += DENTRYSIZ) {
			if(buf[pos] == 'd')
				goto found;
		}
	}


	dirblk = dir1up(dirblk, dirsize, parent, parentsize);
	if(dirblk == 0) {
		werrstr("dir1up: %r");
		return 0;
	}
	dir->path = dirblk;
	++nblks;
	
	blk = dirblk + nblks - 1;
	if(blkread(blk, buf) < 0) {
		werrstr("blkread: %r");
		return -1;
	}
	pos = 0;
	
found:
	buf[pos] = '+';

	seprint(field, field + sizeof(field), "%ulld", file->qid.path);
	writefield(buf + pos, BLOCK, BLOCKSIZ, field);

	writefield(buf + pos, NAME, NAMESIZ, file->name);

	if(file->qid.type & QTDIR)
	        writefield(buf + pos, TYPE, TYPESIZ, " DIR  ");
	else if(file->qid.type & QTAPPEND)
	        writefield(buf + pos, TYPE, TYPESIZ, " APPD ");
	else if(file->qid.type & QTEXCL)
	        writefield(buf + pos, TYPE, TYPESIZ, " EXCL ");
	else
	        writefield(buf + pos, TYPE, TYPESIZ, " FILE ");

	seprint(field, field + sizeof(field), "%lld", file->length);
	writefield(buf + pos, SIZE, SIZESIZ, field);

	num2rwx(field, file->mode & 0777);
	writefield(buf + pos, PERMS, PERMSSIZ, field);

	writefield(buf + pos, UID,  UIDSIZ,  file->uid);
	writefield(buf + pos, GID,  GIDSIZ,  file->gid);
	writefield(buf + pos, MUID, MUIDSIZ, file->muid);

	unix2iso(field, file->mtime);
	writefield(buf + pos, MTIME, MTIMESIZ, field);
 
	unix2iso(field, file->atime);
	writefield(buf + pos, ATIME, ATIMESIZ, field);


	if(blkwrite(blk, buf) < 0) {
		werrstr("blkwrite: %r");
		return -1;
	}
	INCR_VERS(dir->vers);

	pos = getdentry(parentblk, parentsize, dirblk);
	if(pos == 0) {
		werrstr("getdentry: %r");
		return -1;
	}
	blk = pos / BLKSZ + (pos % BLKSZ > 0);
	pos = pos % BLKSZ;
	if(blkread(blk, buf) < 0) {
		werrstr("blkread: %r");
		return -1;
	}

	getfield(buf + pos, SIZE, SIZESIZ, field);
	u64int size = strtoull(field, nil, 10);
	seprint(field, field + sizeof(field), "%ulld", size);
	writefield(buf + pos, SIZE, SIZESIZ, field);
	if(blkwrite(blk, buf) < 0) {
		werrstr("blkwrite: %r");
		return -1;
	}
	INCR_VERS(parent->vers);


	return 0;
}

</pre>
</p>]]></description></item>
<item>
<guid isPermaLink="true">http://okturing.com:80/?id=21895</guid>
<pubDate>Fri, 11 Sep 2026 11:56:08 -0400</pubDate>
<title>OK, turing. 21895</title>
<link>http://okturing.com:80/?id=21895</link>
<description><![CDATA[
<pre>
diff c2a936a02473681c2733ffbe154172e195f434a9 uncommitted
--- a/sys/src/libdraw/alloc.c
+++ b/sys/src/libdraw/alloc.c
@@ -17,13 +17,11 @@
 _allocimage(Image *ai, Display *d, Rectangle r, ulong chan, int repl, ulong col, int screenid, int refresh)
 {
 	uchar *a;
-	char *err;
 	Image *i;
 	Rectangle clipr;
 	int id;
 	int depth;
 
-	err = nil;
 	i = nil;
 
 	if(badrect(r)){
@@ -37,12 +35,9 @@
 
 	depth = chantodepth(chan);
 	if(depth == 0){
-		err = "bad channel descriptor";
+		werrstr("bad channel descriptor");
     Error:
-		if(err != nil)
-			werrstr("allocimage: %s", err);
-		else
-			werrstr("allocimage: %r");
+		werrstr("allocimage: %r");
 		free(i);
 		return nil;
 	}
@@ -110,27 +105,26 @@
 namedimage(Display *d, char *name)
 {
 	uchar *a;
-	char *err, buf[12*12+1];
+	char buf[12*12+1];
 	Image *i;
 	int id, n;
 	ulong chan;
 
-	err = nil;
 	i = nil;
 
+	if(name == nil || name[0] == '\0'){
+		werrstr("namedimage: name can't be empty");
+		return nil;
+	}
+
 	n = strlen(name);
-	if(n >= 256){
-		err = "name too long";
+	if(n > 255){
+		werrstr("name too long");
     Error:
-		if(err != nil)
-			werrstr("namedimage: %s", err);
-		else
-			werrstr("namedimage: %r");
+		werrstr("namedimage: %r");
 		free(i);
 		return nil;
 	}
-	/* flush pending data so we don't get error allocating the image */
-	flushimage(d, 0);
 	_lockdisplay(d);
 	a = bufimage(d, 1+4+1+n);
 	if(a == nil){
@@ -157,7 +151,6 @@
 
 	i = malloc(sizeof(Image));
 	if(i == nil){
-	Error1:
 		_lockdisplay(d);
 		a = bufimage(d, 1+4);
 		if(a != nil){
@@ -171,9 +164,10 @@
 	}
 	i->display = d;
 	i->id = id;
-	if((chan=strtochan(buf+2*12))==0){
-		werrstr("bad channel '%.12s' from devdraw", buf+2*12);
-		goto Error1;
+	if((chan = strtochan(buf+2*12)) == 0){
+		werrstr("namedimage: bad channel '%.12s' from devdraw", buf+2*12);
+		_freeimage1(i);
+		return nil;
 	}
 	i->chan = chan;
 	i->depth = chantodepth(chan);
@@ -197,7 +191,16 @@
 	uchar *a;
 	int n;
 
+	if(name == nil || name[0] == '\0'){
+		werrstr("nameimage: name can't be empty");
+		return 0;
+	}
+
 	n = strlen(name);
+	if(n > 255){
+		werrstr("nameimage: name too long");
+		return 0;
+	}
 	_lockdisplay(i->display);
 	a = bufimage(i->display, 1+4+1+1+n);
 	if(a == nil){
@@ -224,6 +227,7 @@
 
 	if(i == nil || i->display == nil)
 		return 0;
+
 	d = i->display;
 	_lockdisplay(d);
 	a = bufimage(d, 1+4);
--- a/sys/src/libdraw/getrect.c
+++ b/sys/src/libdraw/getrect.c
@@ -109,11 +109,11 @@
 			freetmp();
 	if(tmp[0] == 0){
 		r = Rect(0, 0, max(Dx(display->screenimage->r), Dx(rc)), W);
-		tmp[0] = allocimage(display, r, screen->chan, 0, -1);
-		tmp[1] = allocimage(display, r, screen->chan, 0, -1);
+		tmp[0] = allocimage(display, r, screen->chan, 0, DNofill);
+		tmp[1] = allocimage(display, r, screen->chan, 0, DNofill);
 		r = Rect(0, 0, W, max(Dy(display->screenimage->r), Dy(rc)));
-		tmp[2] = allocimage(display, r, screen->chan, 0, -1);
-		tmp[3] = allocimage(display, r, screen->chan, 0, -1);
+		tmp[2] = allocimage(display, r, screen->chan, 0, DNofill);
+		tmp[3] = allocimage(display, r, screen->chan, 0, DNofill);
 		red = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DRed);
 		if(tmp[0]==0 || tmp[1]==0 || tmp[2]==0 || tmp[3]==0 || red==0){
 			freetmp();
--- a/sys/src/libdraw/window.c
+++ b/sys/src/libdraw/window.c
@@ -162,8 +162,6 @@
 			return;
 		}
 
-	if(n==0)
-		return;
 	_lockdisplay(d);
 	b = bufimage(d, 1+1+2+4*n);
 	if(b == nil){

</pre>
</p>]]></description></item>
<item>
<guid isPermaLink="true">http://okturing.com:80/?id=21893</guid>
<pubDate>Fri, 11 Sep 2026 11:34:37 -0400</pubDate>
<title>OK, turing. 21893</title>
<link>http://okturing.com:80/?id=21893</link>
<description><![CDATA[
<pre>
left to right	() [] -> .
right to left	! ~ ++ -- - (type) * & sizeof
left to right	* / %
left to right	+ -
left to right	<< >>
left to right	< <= > >=
left to right	== !=
left to right	&
left to right	^
left to right	|
left to right	&&
left to right	||
right to left	?:
right to left	= += -+ etc.
left to right	,

</pre>
</p>]]></description></item>
<item>
<guid isPermaLink="true">http://okturing.com:80/?id=21885</guid>
<pubDate>Thu, 10 Sep 2026 16:41:52 -0400</pubDate>
<title>OK, turing. 21885</title>
<link>http://okturing.com:80/?id=21885</link>
<description><![CDATA[
<pre>
#!/bin/rc

fn cleanup{
	echo $user has left the building >> /n/9chat/chat
	echo clean>/mnt/acme/$chatwinid/ctl
	echo del>/mnt/acme/$chatwinid/ctl
	echo clean>/mnt/acme/$inwinid/ctl	
	echo del>/mnt/acme/$inwinid/ctl	
	echo kill>/proc/$apid/ctl
	exit
}

cd /mnt/acme/new

chatwinid=`{cat ctl | awk '{print $1}'}

srv tcp!chat.only9fans.com!9990 chat.only9fans.com /n/9chat

if(~ $#* 1) {
user=$1
}

echo join $user to chat>>/n/9chat/chat

echo name chat-$user-$chatwinid >ctl
echo nomenu >ctl
echo scratch >ctl

cat  /n/9chat/chat >body &
catpid=$apid;

cd /mnt/acme/new
inwinid=`{cat ctl | awk '{print $1}'}
echo name chat-input-$inwinid>ctl
echo cleartag>ctl
echo ' Send Bye '>tag
echo show>ctl
echo nomenu>ctl
echo scratch>ctl


fn send{ 

}
cat /mnt/acme/$inwinid/event >[2]/dev/null | while(event=`{read}) {
	switch($event(1)) {

		case Mx*
			switch($event(5)) {
				case Send
					cat /mnt/acme/$inwinid/body | sed '1s/^/'$user' → /'  >>/n/9chat/chat
					 echo -n , > /mnt/acme/$inwinid/addr
					 echo -n '' > /mnt/acme/$inwinid/data
				case Bye
					cleanup
			}
		case KI*
			switch($event(5)) {
				case 
					cat /mnt/acme/$inwinid/body | sed '1s/^/'$user' → /' | tr -d '' >/n/9chat/chat
					 echo -n , > /mnt/acme/$inwinid/addr
					 echo -n '' > /mnt/acme/$inwinid/data

			}
	}
}



</pre>
</p>]]></description></item>
</channel></rss>

