yenc news/mail decoder. "Please thake these files as part of the Plan9 distribution of you wish" -Steve Notes: Mon Apr 5 17:38:50 EDT 2004 rsc i put this in /n/sources/steve/ydec. i don't think it's generally useful enough to put into the distribution. Reference: /n/sources/patch/sorry/ydec Date: Mon Apr 5 23:39:10 CES 2004 Reviewed-by: rsc --- /usr/local/sys/src/cmd/ydec/ydec.c Thu Jan 1 00:00:00 1970 +++ /usr/local/sys/src/cmd/ydec/ydec.c Mon Apr 5 23:39:10 2004 @@ -0,0 +1,175 @@ +/* yenc file decoder + * + * Please read www.exit109.com/~jeremy/news/yenc.html + * "Why Yenc is bad for Usenet" before adding an encoder. + */ +#include +#include +#include +#include + +static int Verbose = 0; +static ulong *Crctab; +static Biobuf bout; + +int +yydec(char *file, Biobuf *bi) +{ + uchar c; + char *name, *buf, *p, *q; + static int totgot = 0; + static int nextpart = 1; + unsigned long crc, ecrc; + int got, line, part, size, esize, begin, end; + + got = 0; + crc = 0; + part = 0; + name = 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,"line=")) == nil) + sysfatal("%s - no line= in =ybegin\n", file); + line = 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 = &bin; + + 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); +} --- /usr/local/sys/man/1/ydec Thu Jan 1 00:00:00 1970 +++ /usr/local/sys/man/1/ydec Mon Apr 5 23:39:10 2004 @@ -0,0 +1,30 @@ +.TH ydec 1 +.SH NAME +ydec \- decode \fIyenc\fR encoded files. +.SH SYNOPSIS +.B ydec +[ +.BI -v +] [ +.B file... +] +.SH DESCRIPTION +.I Ydec +decodes the given email or news files (or standard input if none) +to a standard output. If the \fB-v\fR option is supplied it prints some +information about decoded file on standard error. +.PP +Multipart files can be decoded but must be presented in order. +.PP +Yenc is a depricated and thus no encoder is supplied, +for further information see www.exit109.com/~jeremy/news/yenc.html +"Why Yenc is bad for Usenet". +.PP +.SH EXAMPLE +.EX + nntpfs + cd /mnt/news/alt/binaries/sounds/mp3/blues + ydec 1234*/body | ydec | mp3 +.EE +.SH SOURCE +.B /sys/src/cmd/ydec.c