Plan 9 from Bell Labs’s /usr/web/sources/contrib/steve/misc/ydec.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


/* yenc file decoder
 *
 * Please read www.exit109.com/~jeremy/news/yenc.html
 * "Why Yenc is bad for Usenet" before adding an encoder.
 */
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <flate.h>

static int Verbose = 0;
static ulong *Crctab;
static Biobuf bout;

int
yydec(char *file, Biobuf *bi)
{
	uchar c;
	char *name, *buf, *p;
	static int totgot = 0;
	static int nextpart = 1;
	unsigned long crc, ecrc;
	int got, part, size, esize, begin, end;

	got = 0;
	crc = 0;
	part = 0;
	name = 0;
	size = 0;
	begin = 0;
	end = 0;
	ecrc = 0;
	while((buf = Brdline(bi, '\n')) != nil){
		if ((p = strchr(buf, '\n')) != nil)
			*p = 0;	
		if ((p = strchr(buf, '\r')) != nil)
			*p = 0;	
		if (strncmp(buf, "=ybegin ", 8)==0) {
			if ((p = strstr(buf,"name=")) == nil)
				sysfatal("%s - no name= in =ybegin\n", file);
			name = strdup(p+5);

			if ((p = strstr(buf,"size=")) == nil)
				sysfatal("%s - no size= in =ybegin\n", file);
			size = atoi(p+5);

			if ((p = strstr(buf,"part=")) != nil)
				part = atoi(p+5);
			break;
		}
	}

	if (part){
		if ((buf = Brdline(bi, '\n')) == nil)
			sysfatal("%s - unexpected EOF\n", file);
		if ((p = strchr(buf, '\n')) != nil)
			*p = 0;	
		if ((p = strchr(buf, '\r')) != nil)
			*p = 0;	
		if (strncmp(buf, "=ypart ", 7) != 0)
			sysfatal("%s - no =ypart in multipart file\n", file);

		if ((p = strstr(buf, "end=")) == nil)
			sysfatal("%s - no end= in =ypart\n", file);
		end = atol(p+4);

		if ((p = strstr(buf, "begin=")) == nil)
			sysfatal("%s - no begin= in =ypart\n", file);
		begin = atol(p+6);
	}

	if (name == nil)
		sysfatal("%s - =ybegin not found\n", file);

	if (Verbose && part == 0 || part == 1)
		fprint(2, "%s %d bytes\n", name, size);

	if (part && part != nextpart)
		sysfatal("%s - got part=%d, wanted part=%d\n", file, part, nextpart);

	while (1){
		if ((buf = Brdline(bi, '\n')) == nil)
			sysfatal("%s - unexpected EOF\n", file);
		if ((p = strchr(buf, '\n')) != nil)
			*p = 0;	
		if ((p = strchr(buf, '\r')) != nil)
			*p = 0;	
		if (strncmp(buf, "=yend ", 6) == 0)
			break;
		for (p = buf; *p;){
			c = (uchar)*p++;
			if (c == '='){
				if ((c = *p++) == 0)
					sysfatal("%s - Esc char (=) at end of line\n", file);
				c = (uchar)(c-64);
			}
			c = (uchar)(c-42);
			Bputc(&bout, c);
			crc = blockcrc(Crctab, crc, &c, 1);
			totgot++;
			got++;
		}
	}

	if ((p = strstr(buf, "size=")) != nil){
		esize = atoi(p+5);
		if (esize != got) {
			fprint(2, "%s corrupted size=%d != %d\n", file, esize, got);
			return 0;
		}
	}

	if (! part){
		if ((p = strstr(buf, "crc32=")) != nil)
			ecrc = strtoul((p+6), nil, 16);
		if (crc != ecrc)
			fprint(2, "%s: %s corrupt crc=%08lux != %08lux\n", argv0, file, crc, ecrc);
		return 0;
	}

	/*
	 * multipart only from here on
	 */
	if ((p = strstr(buf, "pcrc32=")) != nil)
		ecrc = strtoul((p+7), nil, 16);
	if (crc != ecrc)
			fprint(2, "%s: %s corrupt part crc=%08lux != %08lux\n", argv0, file, crc, ecrc);

	if (got != (end - begin + 1))
		sysfatal("%s part=%d wrong size\n", file, part);

	nextpart = part +1;
	return 0;
}

void
usage(void)
{
	fprint(2, "usage: %s [-v] [file...]\n", argv0);
	exits("usage");
}

void
main(int argc, char *argv[])
{
	Biobuf bin, *bi;

	Crctab = mkcrctab(0xedb88320UL);
	Binit(&bin, 0, OREAD);
	Binit(&bout, 1, OWRITE);
	argv0 = *argv;

	ARGBEGIN {
	case 'v':
		Verbose++;
		break;
	default:
		usage();
		break;
	} ARGEND;

	if (argc == 0)
		yydec(*argv, &bin);

	for (; argc--; argv++){
		if ((bi = Bopen(*argv, OREAD)) == nil){
			fprint(2, "%s: %s - cannot read file %r\n", argv0, *argv);
			continue;
		}
		yydec(*argv, bi);
		Bterm(bi);
	}
	Bterm(&bout);
	exits(0);
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].