diff --git a/goldlib/uulib/crc32.h b/goldlib/uulib/crc32.h new file mode 100644 index 0000000..ea1e65b --- /dev/null +++ b/goldlib/uulib/crc32.h @@ -0,0 +1,31 @@ +#ifndef __crc32_h +#define __crc32_h + +/* crc32.h */ + +/* wrapper for gall library */ + +typedef unsigned long crc32_t; +#define Z_NULL 0 + +#define byte(a) ((unsigned char)(a)) + +extern crc32_t __crc32_table[256]; + +static crc32_t updCrc32(unsigned char ch, crc32_t crc) +{ + return (crc32_t)(__crc32_table[byte(crc) ^ byte(ch)] ^ (crc >> 8)); +} + +static crc32_t crc32(crc32_t crc, const unsigned char *buf, unsigned int len) +{ + if (buf == Z_NULL) return 0L; + crc = crc ^ 0xffffffffL; + while (len--) + { + crc = updCrc32(*buf++, crc); + } + return crc ^ 0xffffffffL; +} + +#endif /* __crc32_h */ diff --git a/goldlib/uulib/uucheck.c b/goldlib/uulib/uucheck.c index 9ead574..bee85ae 100644 --- a/goldlib/uulib/uucheck.c +++ b/goldlib/uulib/uucheck.c @@ -846,7 +846,7 @@ UUPreProcessPart (fileread *data, int *ret) } lastvalid = 0; } - else if (lastvalid && data->uudet == lastenc && result->partno <= 0) { + else if (lastvalid && data->uudet == lastenc && result->partno == -1) { result->subfname = _FP_strdup (uucheck_lastname); result->partno = ++lastpart; @@ -859,7 +859,7 @@ UUPreProcessPart (fileread *data, int *ret) else if (data->partno != -1 && result->filename) { result->subfname = _FP_strdup (result->filename); } - else { + else { /* * it's got no info, it's got no begin, and we don't know anything * about this part. Let's forget all about it. diff --git a/goldlib/uulib/uudeview.h b/goldlib/uulib/uudeview.h index 4a1cce9..f073088 100644 --- a/goldlib/uulib/uudeview.h +++ b/goldlib/uulib/uudeview.h @@ -82,6 +82,7 @@ #define BH_ENCODED (4) /* Binhex encoded */ #define PT_ENCODED (5) /* Plain-Text encoded (MIME) */ #define QP_ENCODED (6) /* Quoted-Printable (MIME) */ +#define YENC_ENCODED (7) /* yEnc encoded */ /* * Option indices for GetOption / SetOption @@ -225,7 +226,8 @@ int UUEXPORT UUEncodeMulti _ANSI_ARGS_((FILE *, FILE *, int UUEXPORT UUEncodePartial _ANSI_ARGS_((FILE *, FILE *, char *, int, char *, char *, - int, int, long)); + int, int, long, + unsigned long*)); int UUEXPORT UUEncodeToStream _ANSI_ARGS_((FILE *, FILE *, char *, int, char *, int)); diff --git a/goldlib/uulib/uuencode.c b/goldlib/uulib/uuencode.c index 2013a93..3b46ec4 100644 --- a/goldlib/uulib/uuencode.c +++ b/goldlib/uulib/uuencode.c @@ -46,6 +46,7 @@ #include #include #include +#include /* for braindead systems */ #ifndef SEEK_SET @@ -98,9 +99,9 @@ char * uuencode_id = "$Id$"; */ #ifdef EOLSTRING -static char *eolstring = (char *) EOLSTRING; +static unsigned char *eolstring = (unsigned char *) EOLSTRING; #else -static char *eolstring = (char *) "\012"; +static unsigned char *eolstring = (unsigned char *) "\012"; #endif /* @@ -110,13 +111,15 @@ static char *eolstring = (char *) "\012"; #define CTE_UUENC "x-uuencode" #define CTE_XXENC "x-xxencode" #define CTE_BINHEX "x-binhex" +#define CTE_YENC "x-yenc" #define CTE_TYPE(y) (((y)==B64ENCODED) ? "Base64" : \ ((y)==UU_ENCODED) ? CTE_UUENC : \ ((y)==XX_ENCODED) ? CTE_XXENC : \ ((y)==PT_ENCODED) ? "8bit" : \ ((y)==QP_ENCODED) ? "quoted-printable" : \ - ((y)==BH_ENCODED) ? CTE_BINHEX : "x-oops") + ((y)==BH_ENCODED) ? CTE_BINHEX : \ + ((y)==YENC_ENCODED) ? CTE_YENC : "x-oops") /* * encoding tables @@ -214,7 +217,7 @@ static mimemap mimetable[] = { * encoded bytes per line */ -static int bpl[5] = { 0, 45, 57, 45, 45 }; +static int bpl[8] = { 0, 45, 57, 45, 45, 0, 0, 128 }; /* * tables @@ -240,7 +243,7 @@ char *uuestr_otemp; */ static int -UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile) +UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile, crc32_t *crc, crc32_t *pcrc) { unsigned char *itemp = (unsigned char *) uuestr_itemp; unsigned char *otemp = (unsigned char *) uuestr_otemp; @@ -251,7 +254,7 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile) if (outfile==NULL || infile==NULL || (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&& - encoding!=PT_ENCODED&&encoding!=QP_ENCODED)) { + encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_PARM_CHECK), "UUEncodeStream()"); return UURET_ILLVAL; @@ -264,12 +267,12 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile) if (encoding == PT_ENCODED || encoding == QP_ENCODED) { while (!feof (infile) && (linperfile <= 0 || line < linperfile)) { - if (_FP_fgets ((char *)itemp, 255, infile) == NULL) { + if (_FP_fgets ((char *) itemp, 255, infile) == NULL) { break; } itemp[255] = '\0'; - count = strlen ((char *)itemp); + count = strlen ((char *) itemp); llen = 0; optr = otemp; @@ -291,8 +294,8 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile) if (count > 0 && itemp[count-1] == '\n') { itemp[--count] = '\0'; if (fwrite (itemp, 1, count, outfile) != count || - fwrite (eolstring, 1, - strlen(eolstring), outfile) != strlen (eolstring)) { + fwrite ((char *) eolstring, 1, + strlen((char *) eolstring), outfile) != strlen ((char *) eolstring)) { return UURET_IOERR; } } @@ -337,8 +340,8 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile) } if (fwrite (otemp, 1, llen, outfile) != llen || - fwrite (eolstring, 1, - strlen(eolstring), outfile) != strlen (eolstring)) { + fwrite ((char *) eolstring, 1, + strlen((char *) eolstring), outfile) != strlen ((char *) eolstring)) { return UURET_IOERR; } @@ -353,8 +356,8 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile) otemp[2] = HexEncodeTable[itemp[index-1] & 0x0f]; if (fwrite (otemp, 1, 3, outfile) != 3 || - fwrite (eolstring, 1, - strlen(eolstring), outfile) != strlen (eolstring)) { + fwrite ((char *) eolstring, 1, + strlen((char *) eolstring), outfile) != strlen ((char *) eolstring)) { return UURET_IOERR; } } @@ -385,8 +388,8 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile) llen++; if (fwrite (otemp, 1, llen, outfile) != llen || - fwrite (eolstring, 1, - strlen(eolstring), outfile) != strlen (eolstring)) { + fwrite ((char *) eolstring, 1, + strlen((char *) eolstring), outfile) != strlen ((char *) eolstring)) { return UURET_IOERR; } @@ -402,6 +405,99 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile) return UURET_OK; } + /* + * Special handling for yEnc + */ + + if (encoding == YENC_ENCODED) { + llen = 0; + optr = otemp; + + while (!feof (infile) && (linperfile <= 0 || line < linperfile)) { + if ((count = fread (itemp, 1, 128, infile)) != 128) { + if (count == 0) { + break; + } + else if (ferror (infile)) { + return UURET_IOERR; + } + } + + if (pcrc) + *pcrc = crc32(*pcrc, itemp, count); + if (crc) + *crc = crc32(*crc, itemp, count); + + line++; + + /* + * Busy Callback + */ + + if (UUBUSYPOLL(ftell(infile)-progress.foffset,progress.fsize)) { + UUMessage (uuencode_id, __LINE__, UUMSG_NOTE, + uustring (S_ENCODE_CANCEL)); + return UURET_CANCEL; + } + + for (index=0; index 127) { + if (fwrite (otemp, 1, llen, outfile) != llen || + fwrite ((char *) eolstring, 1, + strlen((char *) eolstring), outfile) != strlen ((char *) eolstring)) { + return UURET_IOERR; + } + llen = 0; + optr = otemp; + } + + switch ((char) ((int) itemp[index] + 42)) { + case '\0': + case '\t': + case '\n': + case '\r': + case '=': + case '\033': + *optr++ = '='; + *optr++ = (char) ((int) itemp[index] + 42 + 64); + llen += 2; + break; + + case '.': + if (llen == 0) { + *optr++ = '='; + *optr++ = (char) ((int) itemp[index] + 42 + 64); + llen += 2; + } + else { + *optr++ = (char) ((int) itemp[index] + 42); + llen++; + } + break; + + default: + *optr++ = (char) ((int) itemp[index] + 42); + llen++; + break; + } + } + } + + /* + * write last line + */ + + if (llen) { + if (fwrite (otemp, 1, llen, outfile) != llen || + fwrite ((char *) eolstring, 1, + strlen((char *) eolstring), outfile) != strlen ((char *) eolstring)) { + return UURET_IOERR; + } + } + + return UURET_OK; + } + /* * Handling for binary encodings */ @@ -452,52 +548,49 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile) * Main encoding */ - if (encoding == UU_ENCODED || encoding == XX_ENCODED || - encoding == B64ENCODED) { - for (index=0; index<=count-3; index+=3, llen+=4) { - *optr++ = table[itemp[index] >> 2]; - *optr++ = table[((itemp[index ] & 0x03) << 4)|(itemp[index+1] >> 4)]; - *optr++ = table[((itemp[index+1] & 0x0f) << 2)|(itemp[index+2] >> 6)]; - *optr++ = table[ itemp[index+2] & 0x3f]; + for (index=0; index<=count-3; index+=3, llen+=4) { + *optr++ = table[itemp[index] >> 2]; + *optr++ = table[((itemp[index ] & 0x03) << 4)|(itemp[index+1] >> 4)]; + *optr++ = table[((itemp[index+1] & 0x0f) << 2)|(itemp[index+2] >> 6)]; + *optr++ = table[ itemp[index+2] & 0x3f]; + } + + /* + * Special handling for incomplete lines + */ + + if (index != count) { + if (encoding == B64ENCODED) { + if (count - index == 2) { + *optr++ = table[itemp[index] >> 2]; + *optr++ = table[((itemp[index ] & 0x03) << 4) | + ((itemp[index+1] & 0xf0) >> 4)]; + *optr++ = table[((itemp[index+1] & 0x0f) << 2)]; + *optr++ = '='; + } + else if (count - index == 1) { + *optr++ = table[ itemp[index] >> 2]; + *optr++ = table[(itemp[index] & 0x03) << 4]; + *optr++ = '='; + *optr++ = '='; + } + llen += 4; } - - /* - * Special handling for incomplete lines - */ - - if (index != count) { - if (encoding == B64ENCODED) { - if (count - index == 2) { - *optr++ = table[itemp[index] >> 2]; - *optr++ = table[((itemp[index ] & 0x03) << 4) | - ((itemp[index+1] & 0xf0) >> 4)]; - *optr++ = table[((itemp[index+1] & 0x0f) << 2)]; - *optr++ = '='; - } - else if (count - index == 1) { - *optr++ = table[ itemp[index] >> 2]; - *optr++ = table[(itemp[index] & 0x03) << 4]; - *optr++ = '='; - *optr++ = '='; - } - llen += 4; + else if (encoding == UU_ENCODED || encoding == XX_ENCODED) { + if (count - index == 2) { + *optr++ = table[itemp[index] >> 2]; + *optr++ = table[((itemp[index ] & 0x03) << 4) | + ( itemp[index+1] >> 4)]; + *optr++ = table[((itemp[index+1] & 0x0f) << 2)]; + *optr++ = table[0]; } - else { - if (count - index == 2) { - *optr++ = table[itemp[index] >> 2]; - *optr++ = table[((itemp[index ] & 0x03) << 4) | - ( itemp[index+1] >> 4)]; - *optr++ = table[((itemp[index+1] & 0x0f) << 2)]; - *optr++ = table[0]; - } - else if (count - index == 1) { - *optr++ = table[ itemp[index] >> 2]; - *optr++ = table[(itemp[index] & 0x03) << 4]; - *optr++ = table[0]; - *optr++ = table[0]; - } - llen += 4; + else if (count - index == 1) { + *optr++ = table[ itemp[index] >> 2]; + *optr++ = table[(itemp[index] & 0x03) << 4]; + *optr++ = table[0]; + *optr++ = table[0]; } + llen += 4; } } @@ -505,13 +598,13 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile) * end of line */ - tptr = (unsigned char *) eolstring; + tptr = eolstring; while (*tptr) *optr++ = *tptr++; *optr++ = '\0'; - llen += strlen (eolstring); + llen += strlen ((char *) eolstring); if (fwrite (otemp, 1, llen, outfile) != llen) return UURET_IOERR; @@ -534,12 +627,14 @@ UUEncodeMulti (FILE *outfile, FILE *infile, char *infname, int encoding, int res, themode; FILE *theifile; char *ptr; + crc32_t crc; + crc32_t *crcptr=NULL; if (outfile==NULL || (infile == NULL && infname==NULL) || (outfname==NULL && infname==NULL) || (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&& - encoding!=PT_ENCODED&&encoding!=QP_ENCODED)) { + encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_PARM_CHECK), "UUEncodeMulti()"); return UURET_ILLVAL; @@ -575,7 +670,7 @@ UUEncodeMulti (FILE *outfile, FILE *infile, char *infname, int encoding, theifile = infile; } - if (progress.fsize <= 0) + if (progress.fsize < 0) progress.fsize = -1; _FP_strncpy (progress.curfile, (outfname)?outfname:infname, 256); @@ -608,22 +703,40 @@ UUEncodeMulti (FILE *outfile, FILE *infile, char *infname, int encoding, * print sub-header */ - fprintf (outfile, "Content-Type: %s%s", - (mimetype)?mimetype:"Application/Octet-Stream", - eolstring); - fprintf (outfile, "Content-Transfer-Encoding: %s%s", - CTE_TYPE(encoding), eolstring); - fprintf (outfile, "Content-Disposition: attachment; filename=\"%s\"%s", - UUFNameFilter ((outfname)?outfname:infname), eolstring); - fprintf (outfile, "%s", eolstring); + if (encoding != YENC_ENCODED) { + fprintf (outfile, "Content-Type: %s%s", + (mimetype)?mimetype:"Application/Octet-Stream", + (char *) eolstring); + fprintf (outfile, "Content-Transfer-Encoding: %s%s", + CTE_TYPE(encoding), (char *) eolstring); + fprintf (outfile, "Content-Disposition: attachment; filename=\"%s\"%s", + UUFNameFilter ((outfname)?outfname:infname), (char *) eolstring); + fprintf (outfile, "%s", (char *) eolstring); + } if (encoding == UU_ENCODED || encoding == XX_ENCODED) { fprintf (outfile, "begin %o %s%s", (themode) ? themode : 0644, UUFNameFilter ((outfname)?outfname:infname), - eolstring); + (char *) eolstring); } - if ((res = UUEncodeStream (outfile, theifile, encoding, 0)) != UURET_OK) { + else if (encoding == YENC_ENCODED) { + crc = crc32(0L, Z_NULL, 0); + crcptr = &crc; + if (progress.fsize == -1) { + fprintf (outfile, "=ybegin line=128 name=%s%s", + UUFNameFilter ((outfname)?outfname:infname), + (char *) eolstring); + } + else { + fprintf (outfile, "=ybegin line=128 size=%ld name=%s%s", + progress.fsize, + UUFNameFilter ((outfname)?outfname:infname), + (char *) eolstring); + } + } + + if ((res = UUEncodeStream (outfile, theifile, encoding, 0, crcptr, NULL)) != UURET_OK) { if (res != UURET_CANCEL) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_ERR_ENCODING), @@ -633,16 +746,32 @@ UUEncodeMulti (FILE *outfile, FILE *infile, char *infname, int encoding, progress.action = 0; return res; } + if (encoding == UU_ENCODED || encoding == XX_ENCODED) { fprintf (outfile, "%c%s", (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0], - eolstring); - fprintf (outfile, "end%s", eolstring); + (char *) eolstring); + fprintf (outfile, "end%s", (char *) eolstring); } + else if (encoding == YENC_ENCODED) { + if (progress.fsize == -1) { + fprintf (outfile, "=yend crc32=%08lx%s", + crc, + (char *) eolstring); + } + else { + fprintf (outfile, "=yend size=%ld crc32=%08lx%s", + progress.fsize, + crc, + (char *) eolstring); + } + } + /* * empty line at end does no harm */ - fprintf (outfile, "%s", eolstring); + + fprintf (outfile, "%s", (char *) eolstring); if (infile==NULL) fclose (theifile); @@ -659,20 +788,23 @@ int UUEXPORT UUEncodePartial (FILE *outfile, FILE *infile, char *infname, int encoding, char *outfname, char *mimetype, - int filemode, int partno, long linperfile) + int filemode, int partno, long linperfile, + crc32_t *crcptr) { mimemap *miter=mimetable; static FILE *theifile; - int themode, numparts; + int themode, numparts = 1; struct stat finfo; long thesize; char *ptr; int res; + crc32_t pcrc; + crc32_t *pcrcptr=NULL; if ((outfname==NULL&&infname==NULL) || partno<=0 || (infile == NULL&&infname==NULL) || outfile==NULL || (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&& - encoding!=PT_ENCODED&&encoding!=QP_ENCODED)) { + encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_PARM_CHECK), "UUEncodePartial()"); return UURET_ILLVAL; @@ -713,7 +845,7 @@ UUEncodePartial (FILE *outfile, FILE *infile, uustring (S_STAT_ONE_PART)); numparts = 1; themode = (filemode)?filemode:0644; - thesize = 0; + thesize = -1; } else { if (linperfile <= 0) @@ -730,7 +862,7 @@ UUEncodePartial (FILE *outfile, FILE *infile, _FP_strncpy (progress.curfile, (outfname)?outfname:infname, 256); - progress.totsize = (thesize>0) ? thesize : -1; + progress.totsize = (thesize>=0) ? thesize : -1; progress.partno = 1; progress.numparts = numparts; progress.percent = 0; @@ -758,23 +890,65 @@ UUEncodePartial (FILE *outfile, FILE *infile, * print sub-header */ - fprintf (outfile, "MIME-Version: 1.0%s", eolstring); - fprintf (outfile, "Content-Type: %s%s", - (mimetype)?mimetype:"Application/Octet-Stream", - eolstring); - fprintf (outfile, "Content-Transfer-Encoding: %s%s", - CTE_TYPE(encoding), eolstring); - fprintf (outfile, "Content-Disposition: attachment; filename=\"%s\"%s", - UUFNameFilter ((outfname)?outfname:infname), eolstring); - fprintf (outfile, "%s", eolstring); + if (encoding != YENC_ENCODED) { + fprintf (outfile, "MIME-Version: 1.0%s", (char *) eolstring); + fprintf (outfile, "Content-Type: %s%s", + (mimetype)?mimetype:"Application/Octet-Stream", + (char *) eolstring); + fprintf (outfile, "Content-Transfer-Encoding: %s%s", + CTE_TYPE(encoding), (char *) eolstring); + fprintf (outfile, "Content-Disposition: attachment; filename=\"%s\"%s", + UUFNameFilter ((outfname)?outfname:infname), (char *) eolstring); + } + fprintf (outfile, "%s", (char *) eolstring); + /* * for the first part of UU or XX messages, print a begin line */ + if (encoding == UU_ENCODED || encoding == XX_ENCODED) { fprintf (outfile, "begin %o %s%s", (themode) ? themode : ((filemode)?filemode:0644), - UUFNameFilter ((outfname)?outfname:infname), eolstring); + UUFNameFilter ((outfname)?outfname:infname), (char *) eolstring); + } + } + if (encoding == YENC_ENCODED) { + pcrc = crc32(0L, Z_NULL, 0); + pcrcptr = &pcrc; + if (numparts != 1) { + if (progress.totsize == -1) { + fprintf (outfile, "=ybegin part=%d line=128 name=%s%s", + partno, + UUFNameFilter ((outfname)?outfname:infname), + (char *) eolstring); + } + else { + fprintf (outfile, "=ybegin part=%d line=128 size=%ld name=%s%s", + partno, + progress.totsize, + UUFNameFilter ((outfname)?outfname:infname), + (char *) eolstring); + } + + fprintf (outfile, "=ypart begin=%ld end=%ld%s", + (partno-1)*linperfile*128+1, + (partno*linperfile*128) < progress.totsize ? + (partno*linperfile*128) : progress.totsize, + (char *) eolstring); + } + else { + if (progress.totsize == -1) { + fprintf (outfile, "=ybegin line=128 name=%s%s", + UUFNameFilter ((outfname)?outfname:infname), + (char *) eolstring); + } + else { + fprintf (outfile, "=ybegin line=128 size=%ld name=%s%s", + progress.totsize, + UUFNameFilter ((outfname)?outfname:infname), + (char *) eolstring); + } } } @@ -797,8 +971,8 @@ UUEncodePartial (FILE *outfile, FILE *infile, progress.action = UUACT_ENCODING; - if ((res = UUEncodeStream (outfile, theifile, - encoding, linperfile)) != UURET_OK) { + if ((res = UUEncodeStream (outfile, theifile, encoding, linperfile, + crcptr, pcrcptr)) != UURET_OK) { if (infile==NULL) fclose (theifile); if (res != UURET_CANCEL) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, @@ -809,15 +983,33 @@ UUEncodePartial (FILE *outfile, FILE *infile, progress.action = 0; return res; } + /* * print end line */ + if (feof (theifile) && (encoding == UU_ENCODED || encoding == XX_ENCODED)) { fprintf (outfile, "%c%s", (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0], - eolstring); - fprintf (outfile, "end%s", eolstring); + (char *) eolstring); + fprintf (outfile, "end%s", (char *) eolstring); + } + else if (encoding == YENC_ENCODED) { + if (numparts != 1) { + fprintf (outfile, "=yend size=%ld part=%d pcrc32=%08lx", + (partno*linperfile*128) < progress.totsize ? + linperfile*128 : (progress.totsize-(partno-1)*linperfile*128), + partno, + pcrc); + } + else { + fprintf (outfile, "=yend size=%ld", + progress.totsize); + } + if (feof (theifile)) + fprintf (outfile, " crc32=%08lx", *crcptr); + fprintf (outfile, "%s", (char *) eolstring); } /* @@ -825,7 +1017,7 @@ UUEncodePartial (FILE *outfile, FILE *infile, */ if (encoding != PT_ENCODED && encoding != QP_ENCODED) { - fprintf (outfile, "%s", eolstring); + fprintf (outfile, "%s", (char *) eolstring); } if (infile==NULL) { @@ -862,12 +1054,14 @@ UUEncodeToStream (FILE *outfile, FILE *infile, FILE *theifile; int themode; int res; + crc32_t crc; + crc32_t *crcptr=NULL; if (outfile==NULL || (infile == NULL&&infname==NULL) || (outfname==NULL&&infname==NULL) || (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&& - encoding!=PT_ENCODED&&encoding!=QP_ENCODED)) { + encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_PARM_CHECK), "UUEncodeToStream()"); return UURET_ILLVAL; @@ -904,7 +1098,7 @@ UUEncodeToStream (FILE *outfile, FILE *infile, theifile = infile; } - if (progress.fsize <= 0) + if (progress.fsize < 0) progress.fsize = -1; _FP_strncpy (progress.curfile, (outfname)?outfname:infname, 256); @@ -919,9 +1113,25 @@ UUEncodeToStream (FILE *outfile, FILE *infile, fprintf (outfile, "begin %o %s%s", (themode) ? themode : 0644, UUFNameFilter ((outfname)?outfname:infname), - eolstring); + (char *) eolstring); } - if ((res = UUEncodeStream (outfile, theifile, encoding, 0)) != UURET_OK) { + else if (encoding == YENC_ENCODED) { + crc = crc32(0L, Z_NULL, 0); + crcptr = &crc; + if (progress.fsize == -1) { + fprintf (outfile, "=ybegin line=128 name=%s%s", + UUFNameFilter ((outfname)?outfname:infname), + (char *) eolstring); + } + else { + fprintf (outfile, "=ybegin line=128 size=%ld name=%s%s", + progress.fsize, + UUFNameFilter ((outfname)?outfname:infname), + (char *) eolstring); + } + } + + if ((res = UUEncodeStream (outfile, theifile, encoding, 0, crcptr, NULL)) != UURET_OK) { if (res != UURET_CANCEL) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_ERR_ENCODING), @@ -931,16 +1141,32 @@ UUEncodeToStream (FILE *outfile, FILE *infile, progress.action = 0; return res; } + if (encoding == UU_ENCODED || encoding == XX_ENCODED) { fprintf (outfile, "%c%s", (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0], - eolstring); - fprintf (outfile, "end%s", eolstring); + (char *) eolstring); + fprintf (outfile, "end%s", (char *) eolstring); } + else if (encoding == YENC_ENCODED) { + if (progress.fsize == -1) { + fprintf (outfile, "=yend crc32=%08lx%s", + crc, + (char *) eolstring); + } + else { + fprintf (outfile, "=yend size=%ld crc32=%08lx%s", + progress.fsize, + crc, + (char *) eolstring); + } + } + /* * empty line at end does no harm */ - fprintf (outfile, "%s", eolstring); + + fprintf (outfile, "%s", (char *) eolstring); if (infile==NULL) fclose (theifile); progress.action = 0; @@ -960,11 +1186,13 @@ UUEncodeToFile (FILE *infile, char *infname, int encoding, char *oname=NULL, *optr, *ptr; FILE *theifile, *outfile; struct stat finfo; + crc32_t pcrc, crc; + crc32_t *pcrcptr=NULL, *crcptr=NULL; if ((diskname==NULL&&infname==NULL) || (outfname==NULL&&infname==NULL) || (infile==NULL&&infname==NULL) || (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&& - encoding!=PT_ENCODED&&encoding!=QP_ENCODED)) { + encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_PARM_CHECK), "UUEncodeToFile()"); return UURET_ILLVAL; @@ -1076,7 +1304,7 @@ UUEncodeToFile (FILE *infile, char *infname, int encoding, _FP_strncpy (progress.curfile, (outfname)?outfname:infname, 256); - progress.totsize = (progress.totsize<=0) ? -1 : progress.totsize; + progress.totsize = (progress.totsize<0) ? -1 : progress.totsize; progress.numparts = numparts; for (part=1; !feof (theifile); part++) { @@ -1132,28 +1360,74 @@ UUEncodeToFile (FILE *infile, char *infname, int encoding, free (oname); return UURET_IOERR; } - fprintf (outfile, "%s", eolstring); - fprintf (outfile, "_=_ %s", eolstring); - if (numparts == -1) - fprintf (outfile, "_=_ Part %03d of file %s%s", - part, UUFNameFilter ((outfname)?outfname:infname), - eolstring); - else - fprintf (outfile, "_=_ Part %03d of %03d of file %s%s", - part, numparts, - UUFNameFilter ((outfname)?outfname:infname), - eolstring); - fprintf (outfile, "_=_ %s", eolstring); - fprintf (outfile, "%s", eolstring); + + if (encoding != YENC_ENCODED) { + fprintf (outfile, "%s", (char *) eolstring); + fprintf (outfile, "_=_ %s", (char *) eolstring); + if (numparts == -1) + fprintf (outfile, "_=_ Part %03d of file %s%s", + part, UUFNameFilter ((outfname)?outfname:infname), + (char *) eolstring); + else + fprintf (outfile, "_=_ Part %03d of %03d of file %s%s", + part, numparts, + UUFNameFilter ((outfname)?outfname:infname), + (char *) eolstring); + fprintf (outfile, "_=_ %s", (char *) eolstring); + fprintf (outfile, "%s", (char *) eolstring); + } if (part==1 && (encoding == UU_ENCODED || encoding == XX_ENCODED)) { fprintf (outfile, "begin %o %s%s", (filemode)?filemode : 0644, UUFNameFilter ((outfname)?outfname:infname), - eolstring); + (char *) eolstring); } + else if (encoding == YENC_ENCODED) { + if (!crcptr) { + crc = crc32(0L, Z_NULL, 0); + crcptr = &crc; + } + pcrc = crc32(0L, Z_NULL, 0); + pcrcptr = &pcrc; + if (numparts != 1) { + if (progress.totsize == -1) { + fprintf (outfile, "=ybegin part=%d line=128 name=%s%s", + part, + UUFNameFilter ((outfname)?outfname:infname), + (char *) eolstring); + } + else { + fprintf (outfile, "=ybegin part=%d line=128 size=%ld name=%s%s", + part, + progress.totsize, + UUFNameFilter ((outfname)?outfname:infname), + (char *) eolstring); + } + + fprintf (outfile, "=ypart begin=%ld end=%ld%s", + (part-1)*linperfile*128+1, + (part*linperfile*128) < progress.totsize ? + (part*linperfile*128) : progress.totsize, + (char *) eolstring); + } + else { + if (progress.totsize == -1) { + fprintf (outfile, "=ybegin line=128 name=%s%s", + UUFNameFilter ((outfname)?outfname:infname), + (char *) eolstring); + } + else { + fprintf (outfile, "=ybegin line=128 size=%ld name=%s%s", + progress.totsize, + UUFNameFilter ((outfname)?outfname:infname), + (char *) eolstring); + } + } + } + if ((res = UUEncodeStream (outfile, theifile, - encoding, linperfile)) != UURET_OK) { + encoding, linperfile, crcptr, pcrcptr)) != UURET_OK) { if (res != UURET_CANCEL) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_ERR_ENCODING), @@ -1167,19 +1441,39 @@ UUEncodeToFile (FILE *infile, char *infname, int encoding, _FP_free (oname); return res; } + if (feof (theifile) && (encoding == UU_ENCODED || encoding == XX_ENCODED)) { fprintf (outfile, "%c%s", (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0], - eolstring); - fprintf (outfile, "end%s", eolstring); + (char *) eolstring); + fprintf (outfile, "end%s", (char *) eolstring); } + else if (encoding == YENC_ENCODED) { + if (numparts != 1) { + fprintf (outfile, "=yend size=%ld part=%d pcrc32=%08lx", + (part*linperfile*128) < progress.totsize ? + linperfile*128 : (progress.totsize-(part-1)*linperfile*128), + part, + pcrc); + } + else { + fprintf (outfile, "=yend size=%ld", + progress.totsize); + } + if (feof (theifile)) + fprintf (outfile, " crc32=%08lx", crc); + fprintf (outfile, "%s", (char *) eolstring); + } + /* * empty line at end does no harm */ - fprintf (outfile, "%s", eolstring); + + fprintf (outfile, "%s", (char *) eolstring); fclose (outfile); } + if (infile==NULL) fclose (theifile); progress.action = 0; _FP_free (oname); @@ -1222,7 +1516,7 @@ UUE_PrepSingleExt (FILE *outfile, FILE *infile, if ((outfname==NULL&&infname==NULL) || (infile==NULL&&infname==NULL) || (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&& - encoding!=PT_ENCODED&&encoding!=QP_ENCODED)) { + encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_PARM_CHECK), "UUE_PrepSingle()"); return UURET_ILLVAL; @@ -1249,34 +1543,45 @@ UUE_PrepSingleExt (FILE *outfile, FILE *infile, return UURET_NOMEM; } - if (subject) - sprintf (subline, "%s (001/001) - [ %s ]", subject, oname); - else - sprintf (subline, "[ %s ] (001/001)", oname); + if (encoding == YENC_ENCODED) { + if (subject) + sprintf (subline, "- %s - %s (001/001)", oname, subject); + else + sprintf (subline, "- %s - (001/001)", oname); + } + else { + if (subject) + sprintf (subline, "%s (001/001) - [ %s ]", subject, oname); + else + sprintf (subline, "[ %s ] (001/001)", oname); + } if (from) { - fprintf (outfile, "From: %s%s", from, eolstring); + fprintf (outfile, "From: %s%s", from, (char *) eolstring); } if (destination) { fprintf (outfile, "%s: %s%s", (isemail)?"To":"Newsgroups", - destination, eolstring); + destination, (char *) eolstring); } - fprintf (outfile, "Subject: %s%s", subline, eolstring); + fprintf (outfile, "Subject: %s%s", subline, (char *) eolstring); if (replyto) { - fprintf (outfile, "Reply-To: %s%s", replyto, eolstring); + fprintf (outfile, "Reply-To: %s%s", replyto, (char *) eolstring); } - fprintf (outfile, "MIME-Version: 1.0%s", eolstring); - fprintf (outfile, "Content-Type: %s; name=\"%s\"%s", - (mimetype)?mimetype:"Application/Octet-Stream", - UUFNameFilter ((outfname)?outfname:infname), - eolstring); - fprintf (outfile, "Content-Transfer-Encoding: %s%s", - CTE_TYPE(encoding), eolstring); - fprintf (outfile, "%s", eolstring); + if (encoding != YENC_ENCODED) { + fprintf (outfile, "MIME-Version: 1.0%s", (char *) eolstring); + fprintf (outfile, "Content-Type: %s; name=\"%s\"%s", + (mimetype)?mimetype:"Application/Octet-Stream", + UUFNameFilter ((outfname)?outfname:infname), + (char *) eolstring); + fprintf (outfile, "Content-Transfer-Encoding: %s%s", + CTE_TYPE(encoding), (char *) eolstring); + } + + fprintf (outfile, "%s", (char *) eolstring); res = UUEncodeToStream (outfile, infile, infname, encoding, outfname, filemode); @@ -1318,10 +1623,12 @@ UUE_PrepPartialExt (FILE *outfile, FILE *infile, char *subline, *oname; long thesize; int res, len; + static crc32_t crc; + crc32_t *crcptr=NULL; if ((outfname==NULL&&infname==NULL) || (infile==NULL&&infname==NULL) || (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&& - encoding!=PT_ENCODED&&encoding!=QP_ENCODED)) { + encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_PARM_CHECK), "UUE_PrepPartial()"); return UURET_ILLVAL; @@ -1333,6 +1640,7 @@ UUE_PrepPartialExt (FILE *outfile, FILE *infile, /* * if first part, get information about the file */ + if (partno == 1) { if (infile==NULL) { if (stat (infname, &finfo) == -1) { @@ -1363,7 +1671,7 @@ UUE_PrepPartialExt (FILE *outfile, FILE *infile, uustring (S_STAT_ONE_PART)); numparts = 1; themode = (filemode)?filemode:0644; - thesize = 0; + thesize = -1; } else { if (linperfile <= 0) @@ -1388,6 +1696,7 @@ UUE_PrepPartialExt (FILE *outfile, FILE *infile, } theifile = infile; } + /* * if there's one part only, don't use Message/Partial */ @@ -1402,6 +1711,7 @@ UUE_PrepPartialExt (FILE *outfile, FILE *infile, /* * we also need a unique ID */ + sprintf (mimeid, "UUDV-%ld.%ld.%s", (long) time(NULL), thesize, (strlen(oname)>16)?"oops":oname); @@ -1414,40 +1724,57 @@ UUE_PrepPartialExt (FILE *outfile, FILE *infile, return UURET_NOMEM; } - if (subject) - sprintf (subline, "%s (%03d/%03d) - [ %s ]", - subject, partno, numparts, oname); - else - sprintf (subline, "[ %s ] (%03d/%03d)", - oname, partno, numparts); + + if (encoding == YENC_ENCODED) { + if (partno == 1) + crc = crc32(0L, Z_NULL, 0); + crcptr = &crc; + if (subject) + sprintf (subline, "- %s - %s (%03d/%03d)", oname, subject, + partno, numparts); + else + sprintf (subline, "- %s - (%03d/%03d)", oname, + partno, numparts); + } + else { + if (subject) + sprintf (subline, "%s (%03d/%03d) - [ %s ]", + subject, partno, numparts, oname); + else + sprintf (subline, "[ %s ] (%03d/%03d)", + oname, partno, numparts); + } if (from) { - fprintf (outfile, "From: %s%s", from, eolstring); + fprintf (outfile, "From: %s%s", from, (char *) eolstring); } if (destination) { fprintf (outfile, "%s: %s%s", (isemail)?"To":"Newsgroups", - destination, eolstring); + destination, (char *) eolstring); } - fprintf (outfile, "Subject: %s%s", subline, eolstring); + fprintf (outfile, "Subject: %s%s", subline, (char *) eolstring); if (replyto) { - fprintf (outfile, "Reply-To: %s%s", replyto, eolstring); + fprintf (outfile, "Reply-To: %s%s", replyto, (char *) eolstring); } - fprintf (outfile, "MIME-Version: 1.0%s", eolstring); - fprintf (outfile, "Content-Type: Message/Partial; number=%d; total=%d;%s", - partno, numparts, eolstring); - fprintf (outfile, "\tid=\"%s\"%s", - mimeid, eolstring); - fprintf (outfile, "%s", eolstring); + if (encoding != YENC_ENCODED) { + fprintf (outfile, "MIME-Version: 1.0%s", (char *) eolstring); + fprintf (outfile, "Content-Type: Message/Partial; number=%d; total=%d;%s", + partno, numparts, (char *) eolstring); + fprintf (outfile, "\tid=\"%s\"%s", + mimeid, (char *) eolstring); + } + + fprintf (outfile, "%s", (char *) eolstring); res = UUEncodePartial (outfile, theifile, infname, encoding, (outfname)?outfname:infname, NULL, - themode, partno, linperfile); + themode, partno, linperfile, crcptr); _FP_free (subline); diff --git a/goldlib/uulib/uulib.c b/goldlib/uulib/uulib.c index 914d732..c497e95 100644 --- a/goldlib/uulib/uulib.c +++ b/goldlib/uulib/uulib.c @@ -233,22 +233,22 @@ static allomap toallocate[] = { { &uuestr_itemp, 256 }, /* from uuencode.c:UUEncodeStream() */ { &uuestr_otemp, 1024 }, { &uulib_msgstring, 1024 }, /* from uulib.c:UUMessage() */ - { &uuncdl_fulline, 260 }, /* from uunconc.c:UUDecodeLine() */ - { &uuncdp_oline, 1024 }, /* from uunconc.c:UUDecodePart() */ + { &uuncdl_fulline, 300 }, /* from uunconc.c:UUDecodeLine() */ + { &uuncdp_oline, 1200 }, /* from uunconc.c:UUDecodePart() */ { &uunconc_UUxlat, 256 * sizeof (int) }, /* from uunconc.c:toplevel */ { &uunconc_UUxlen, 64 * sizeof (int) }, { &uunconc_B64xlat, 256 * sizeof (int) }, { &uunconc_XXxlat, 256 * sizeof (int) }, { &uunconc_BHxlat, 256 * sizeof (int) }, - { &uunconc_save, 3*256 }, /* from uunconc.c:decoding buffer */ + { &uunconc_save, 3*300 }, /* from uunconc.c:decoding buffer */ { &uuscan_shlline, 1024 }, /* from uuscan.c:ScanHeaderLine() */ - { &uuscan_pvvalue, 256 }, /* from uuscan.c:ParseValue() */ - { &uuscan_phtext, 256 }, /* from uuscan.c:ParseHeader() */ - { &uuscan_sdline, 256 }, /* from uuscan.c:ScanData() */ - { &uuscan_sdbhds1, 256 }, - { &uuscan_sdbhds2, 256 }, - { &uuscan_spline, 256 }, /* from uuscan.c:ScanPart() */ - { &uuutil_bhwtmp, 256 }, /* from uuutil.c:UUbhwrite() */ + { &uuscan_pvvalue, 300 }, /* from uuscan.c:ParseValue() */ + { &uuscan_phtext, 300 }, /* from uuscan.c:ParseHeader() */ + { &uuscan_sdline, 300 }, /* from uuscan.c:ScanData() */ + { &uuscan_sdbhds1, 300 }, + { &uuscan_sdbhds2, 300 }, + { &uuscan_spline, 300 }, /* from uuscan.c:ScanPart() */ + { &uuutil_bhwtmp, 300 }, /* from uuutil.c:UUbhwrite() */ { NULL, 0 } }; @@ -1094,6 +1094,9 @@ UUInfoFile (uulist *thefile, void *opaque, else if ((thefile->uudet == UU_ENCODED || thefile->uudet == XX_ENCODED) && strncmp (uugen_inbuffer, "begin ", 6) == 0) break; + else if (thefile->uudet == YENC_ENCODED && + strncmp (uugen_inbuffer, "=ybegin ", 8) == 0) + break; if ((*func) (opaque, uugen_inbuffer)) break; diff --git a/goldlib/uulib/uunconc.c b/goldlib/uulib/uunconc.c index d70e12e..a9ec2ea 100644 --- a/goldlib/uulib/uunconc.c +++ b/goldlib/uulib/uunconc.c @@ -49,6 +49,7 @@ #include #endif +#include #include #include #include @@ -119,6 +120,7 @@ static int uulboundary; */ #define ACAST(s) ((int)(unsigned char)(s)) +#define isnotvalid(c) (ACAST(c) >= 0x80) /* * Initialize decoding tables @@ -297,10 +299,10 @@ UUValidData (char *ptr, int encoding, int *bhflag) int i=0, j, len=0, suspicious=0, flag=0; char *s = ptr; - if ((s == NULL) || !(iscntrl(ACAST(*s)) || isascii(ACAST(*s)))) { - return(0); /* bad string */ + if ((s == NULL) || (*s == '\0')) { + return 0; /* bad string */ } - + while (*s && *s!='\012' && *s!='\015') { s++; len++; @@ -319,6 +321,8 @@ UUValidData (char *ptr, int encoding, int *bhflag) goto _t_B64; case BH_ENCODED: goto _t_Binhex; + case YENC_ENCODED: + return YENC_ENCODED; } _t_Binhex: /* Binhex Test */ @@ -381,8 +385,7 @@ UUValidData (char *ptr, int encoding, int *bhflag) */ while (len--) { - if (!(iscntrl(ACAST(*s)) || isascii(ACAST(*s))) || - (B64xlat[ACAST(*s)] == -1 && *s != '=')) { + if (/* *s < 0 */ isnotvalid(*s) || (B64xlat[ACAST(*s)] == -1 && *s != '=')) { /* allow space characters at the end of the line if we are sure */ /* that this is Base64 encoded data or the line was long enough */ if (((i>=60 && len<=10) || encoding) && *s++==' ') { @@ -474,8 +477,7 @@ UUValidData (char *ptr, int encoding, int *bhflag) } while (len--) { - if (!(iscntrl(ACAST(*s)) || isascii(ACAST(*s))) || - UUxlat[ACAST(*s++)] < 0) { + if (/* *s < 0 */ isnotvalid(*s) || UUxlat[ACAST(*s++)] < 0) { if (encoding==UU_ENCODED) return 0; goto _t_XX; /* bad code character */ } @@ -515,8 +517,7 @@ UUValidData (char *ptr, int encoding, int *bhflag) return 0; /* bad length */ while(len--) { - if (!(iscntrl(ACAST(*s)) || isascii(ACAST(*s))) || - XXxlat[ACAST(*s++)] < 0) { + if(/* *s < 0 */ isnotvalid(*s) || XXxlat[ACAST(*s++)] < 0) { return 0; /* bad code character */ } } @@ -709,6 +710,22 @@ UUDecodeLine (char *s, char *d, int method) while (BHxlat[ACAST(*s)] != -1) uuncdl_fulline[leftover++] = *s++; } + else if (method == YENC_ENCODED) { + while (*s) { + if (*s == '=') { + if (*++s != '\0') { + d[count++] = (char) ((int) *s - 64 - 42); + s++; + } + } + else if (*s == '\n' || *s == '\r') { + s++; /* ignore */ + } + else { + d[count++] = (char) ((int) *s++ - 42); + } + } + } return count; } @@ -886,10 +903,16 @@ UUDecodePart (FILE *datain, FILE *dataout, int *state, char *line=uugen_fnbuffer, *oline=uuncdp_oline; int warning=0, vlc=0, lc[2], hadct=0; int tc=0, tf=0, vflag, haddata=0, haddh=0; + long yefilesize=0, yepartends=0; + crc32_t yepartcrc=crc32(0L, Z_NULL, 0); + static crc32_t yefilecrc=0; static int bhflag=0; size_t count=0; + size_t yepartsize=0; + char *ptr; if (datain == NULL || dataout == NULL) { + yefilecrc = crc32(0L, Z_NULL, 0); bhflag = 0; return UURET_OK; } @@ -910,27 +933,35 @@ UUDecodePart (FILE *datain, FILE *dataout, int *state, uulboundary = -1; + if (method == YENC_ENCODED) { + *state = BEGIN; + } + while (!feof (datain) && *state != DONE && (ftell(datain) 5) tf = tc = 0; vlc = 0; @@ -951,7 +982,7 @@ UUDecodePart (FILE *datain, FILE *dataout, int *state, * try to make sense of data */ - line[255] = '\0'; /* For Safety of string functions */ + line[299] = '\0'; /* For Safety of string functions */ count = 0; if (boundary && line[0]=='-' && line[1]=='-' && @@ -990,9 +1021,9 @@ UUDecodePart (FILE *datain, FILE *dataout, int *state, } if (*state == BEGIN) { - if (strncmp (line, "begin ", 6) == 0 || - strncmp (line, "section ", 8) == 0 || - _FP_strnicmp (line, "
begin ", 11) == 0) {    /* for LYNX */
+      if ((method == UU_ENCODED || method == XX_ENCODED) &&
+	  (strncmp      (line, "begin ",       6) == 0 ||
+	   _FP_strnicmp (line, "
begin ", 11) == 0)) { /* for LYNX */
 	*state = DATA;
 	continue;
       }
@@ -1004,8 +1035,36 @@ UUDecodePart (FILE *datain, FILE *dataout, int *state,
 	else
 	  continue;
       }
-      else
+      else if (method == YENC_ENCODED &&
+	       strncmp (line, "=ybegin ", 8) == 0 &&
+	       _FP_strstr (line, " name=") != NULL) {
+	*state = DATA;
+
+	if ((ptr = _FP_strstr (line, " size=")) != NULL) {
+	  ptr += 6;
+	  yefilesize = atoi (ptr);
+	}
+	else {
+	  yefilesize = -1;
+	}
+
+	if (_FP_strstr (line, " part=") != NULL) {
+	  if (_FP_fgets (line, 299, datain) == NULL) {
+	    break;
+	  }
+
+	  if ((ptr = _FP_strstr (line, " end=")) == NULL) {
+	    break;
+	  }
+       
+	  yepartends = atoi (ptr + 5);
+	}
+	tf = 1;
 	continue;
+      }
+      else {
+	continue;
+      }
       
       tc = tf = vlc = 0;
       lc[0] = lc[1] = 0;
@@ -1017,6 +1076,44 @@ UUDecodePart (FILE *datain, FILE *dataout, int *state,
 	break;
       }
     }
+
+    if (*state == DATA && method == YENC_ENCODED &&
+	strncmp (line, "=yend ", 6) == 0) {
+      if ((ptr = _FP_strstr (line, " pcrc32=")) != NULL) {
+	crc32_t pcrc32 = strtoul (ptr + 8, NULL, 16);
+	if (pcrc32 != yepartcrc) {
+	  UUMessage (uunconc_id, __LINE__, UUMSG_WARNING,
+		     uustring (S_PCRC_MISMATCH), progress.curfile, progress.partno);
+	}
+      }
+      if ((ptr = _FP_strstr (line, " crc32=")) != NULL)
+      {
+	crc32_t fcrc32 = strtoul (ptr + 7, NULL, 16);
+	if (fcrc32 != yefilecrc) {
+	  UUMessage (uunconc_id, __LINE__, UUMSG_WARNING,
+		     uustring (S_CRC_MISMATCH), progress.curfile);
+	}
+      }
+      if ((ptr = _FP_strstr (line, " size=")) != NULL)
+      {
+	size_t size = atol(ptr + 6);
+	if (size != yepartsize && yefilesize != -1) {
+	  if (size != yefilesize)
+	    UUMessage (uunconc_id, __LINE__, UUMSG_WARNING,
+		       uustring (S_PSIZE_MISMATCH), progress.curfile,
+		       progress.partno, yepartsize, size);
+	  else
+	    UUMessage (uunconc_id, __LINE__, UUMSG_WARNING,
+		       uustring (S_SIZE_MISMATCH), progress.curfile,
+		       yepartsize, size);
+	}
+      }
+      if (yepartends == 0 || yepartends >= yefilesize) {
+	*state = DONE;
+      }
+      break;
+    }
+
     if (*state == DATA || *state == END) {
       if (method==B64ENCODED && line[0]=='-' && line[1]=='-' && tc) {
 	break;
@@ -1036,9 +1133,14 @@ UUDecodePart (FILE *datain, FILE *dataout, int *state,
       }
 
       if (vflag == method) {
-	if (tf || (method == UU_ENCODED || method == XX_ENCODED)) {
+	if (tf) {
 	  count  = UUDecodeLine (line, oline, method);
-	  tf     = 1;
+	  if (method == YENC_ENCODED) {
+	    if (yepartends)
+	      yepartcrc = crc32(yepartcrc, (unsigned char *) oline, count);
+	    yefilecrc = crc32(yefilecrc, (unsigned char *) oline, count);
+	    yepartsize += count;
+	  }
 	  vlc++; lc[1]++;
 	}
 	else if (tc == 3) {
@@ -1066,6 +1168,7 @@ UUDecodePart (FILE *datain, FILE *dataout, int *state,
 	else {
 	  _FP_strncpy (save[tc++], line, 256);
 	}
+
 	if (method == UU_ENCODED)
 	  *state = (line[0] == 'M') ? DATA : END;
 	else if (method == XX_ENCODED)
@@ -1084,6 +1187,7 @@ UUDecodePart (FILE *datain, FILE *dataout, int *state,
     else if (*state != DONE) {
       return UURET_NOEND;
     }
+
     if (count) {
       if (method == BH_ENCODED) {
 	if (UUbhwrite (oline, 1, count, dataout) != count) {
diff --git a/goldlib/uulib/uuscan.c b/goldlib/uulib/uuscan.c
index 260dd7f..50f9057 100644
--- a/goldlib/uulib/uuscan.c
+++ b/goldlib/uulib/uuscan.c
@@ -326,8 +326,8 @@ static headers *
 ParseHeader (headers *theheaders, char *line)
 {
   char **variable=NULL;
-  char *value, *ptr, *thenew;
-  int delimit, length;
+  char *value = NULL, *ptr, *thenew;
+  int delimit = 0, length;
 
   if (line == NULL)
     return theheaders;
@@ -417,16 +417,12 @@ ParseHeader (headers *theheaders, char *line)
       }
     }
     variable = NULL;
-    value = NULL;
-    delimit = 0;
   }
   else {
     /*
      * nothing interesting
      */
-    variable = NULL;
-    value = NULL;
-    delimit = 0;
+    return theheaders;
   }
 
   /*
@@ -527,6 +523,7 @@ ScanData (FILE *datei, char *fname, int *errcode,
   int encoding=0, dflag=0, ctline=42;
   int dontcare=0, hadnl=0;
   long preheaders=0, oldposition;
+  long yefilesize=0, yepartends=0;
   size_t dcc, bhopc;
 
   *errcode = UURET_OK;
@@ -550,12 +547,12 @@ ScanData (FILE *datei, char *fname, int *errcode,
 
   while (!feof (datei)) {
     oldposition = ftell (datei);
-    if (_FP_fgets (line, 255, datei) == NULL)
+    if (_FP_fgets (line, 299, datei) == NULL)
       break;
     if (ferror (datei))
       break;
 
-    line[255] = '\0'; /* For Safety of string functions */
+    line[299] = '\0'; /* For Safety of string functions */
 
     /*
      * Make Busy Polls
@@ -671,7 +668,9 @@ ScanData (FILE *datei, char *fname, int *errcode,
       continue;
     }
 
-    if ((strncmp (line, "end", 3) == 0) && result->uudet != BH_ENCODED) {
+    if ((strncmp (line, "end", 3) == 0) &&
+	result->uudet != BH_ENCODED &&
+	result->uudet != YENC_ENCODED) {
       if (result->uudet == B64ENCODED && result->begin)
 	result->uudet = XX_ENCODED;
 
@@ -686,20 +685,16 @@ ScanData (FILE *datei, char *fname, int *errcode,
     hadnl = 0;
 
     /*
-     * Detect a UUDeview/UUCODE-Style headers
+     * Detect a UUDeview-Style header
      */
 
-    if (_FP_strnicmp (line, "_=_ Part ", 9) == 0 ||
-	_FP_strnicmp (line, "section ", 8) == 0) {
+    if (_FP_strnicmp (line, "_=_ Part ", 9) == 0 &&
+	result->uudet != YENC_ENCODED) {
       if (result->uudet) {
 	fseek (datei, oldposition, SEEK_SET);
 	break;
       }
       result->partno = atoi (line + 8);
-      if ((ptr = _FP_stristr (line, " of ")) != NULL) {
-        int maxpno = atoi (ptr + 4);
-        if(maxpno != 0) result->maxpno = maxpno;
-      }
       if ((ptr = _FP_stristr (line, "of file ")) != NULL) {
 	ptr += 8;
 	while (isspace (*ptr)) ptr++;
@@ -726,7 +721,8 @@ ScanData (FILE *datei, char *fname, int *errcode,
      * Some reduced MIME handling. Only use if boundary == NULL. Also
      * accept the "X-Orcl-Content-Type" used by some braindead program.
      */
-    if (boundary == NULL && !ismime && !uu_more_mime) {
+    if (boundary == NULL && !ismime && !uu_more_mime &&
+	result->uudet != YENC_ENCODED) {
       if (_FP_strnicmp (line, "Content-Type", 12) == 0 ||
 	  _FP_strnicmp (line, "X-Orcl-Content-Type", 19) == 0) {
 	/*
@@ -853,6 +849,89 @@ ScanData (FILE *datei, char *fname, int *errcode,
       }
     }
 
+    /*
+     * Detection for yEnc encoding
+     */
+
+    if (strncmp (line, "=ybegin ", 8) == 0 &&
+	_FP_strstr (line, " name=") != NULL) {
+      if ((result->begin || result->end) && !uu_more_mime) {
+	fseek (datei, oldposition, SEEK_SET);
+	break;
+      }
+
+      /*
+       * name continues to the end of the line
+       */
+      
+      _FP_free (result->filename);
+      ptr = _FP_strstr (line, " name=") + 6;
+      result->filename = _FP_strdup (ptr);
+
+      while (isspace (result->filename[strlen(result->filename)-1]))
+	result->filename[strlen(result->filename)-1] = '\0';
+
+      /*
+       * Determine size
+       */
+
+      if ((ptr = _FP_strstr (line, " size=")) != NULL) {
+	ptr += 6;
+	yefilesize = atoi (ptr);
+      }
+      else {
+	yefilesize = -1;
+      }
+
+      /*
+       * check for multipart file and read =ypart line
+       */
+
+      if ((ptr = _FP_strstr (line, " part=")) != NULL) {
+	result->partno = atoi (ptr + 6);
+
+	if (result->partno == 1) {
+	  result->begin = 1;
+	}
+
+	if (_FP_fgets (line, 255, datei) == NULL) {
+	  break;
+	}
+
+	line[255] = '\0';
+
+	if (strncmp (line, "=ypart ", 7) != 0) {
+	  break;
+	}
+
+	if ((ptr = _FP_strstr (line, " end=")) == NULL) {
+	  break;
+	}
+       
+	yepartends = atoi (ptr + 5);
+      }
+      else {
+	result->partno = 1;
+	result->begin = 1;
+      }
+
+      /*
+       * Don't want auto-detection
+       */
+
+      result->uudet = YENC_ENCODED;
+      continue;
+    }
+
+    if (strncmp (line, "=yend ", 6) == 0 &&
+	result->uudet == YENC_ENCODED) {
+      if (yepartends == 0 || yepartends >= yefilesize) {
+	result->end = 1;
+      }
+      if (!uu_more_mime)
+	break;
+    }
+
     /*
      * if we haven't yet found anything encoded, try to find something
      */
@@ -1202,7 +1281,8 @@ ScanData (FILE *datei, char *fname, int *errcode,
     result->begin = result->end = 0;
 
   /* Base64 and BinHex don't have a file mode */
-  if (result->uudet == B64ENCODED || result->uudet == BH_ENCODED)
+  if (result->uudet == B64ENCODED || result->uudet == BH_ENCODED ||
+      result->uudet == YENC_ENCODED)
     result->mode  = 6*64+4*8+4;
 
   /*
@@ -1997,6 +2077,7 @@ ScanPart (FILE *datei, char *fname, int *errcode)
 	return NULL;
       }
     }
+
     /*
      * So this subpart is either plain text or something else. Check
      * the Content-Type and Content-Transfer-Encoding. If the latter
@@ -2009,10 +2090,17 @@ ScanPart (FILE *datei, char *fname, int *errcode)
      * This is done because users might `attach' a uuencoded file, which
      * would then be correctly typed as `text/plain'.
      */
+
     if (_FP_stristr (localenv.ctenc, "base64") != NULL)
       result->uudet = B64ENCODED;
-    else if (_FP_stristr (localenv.ctenc, "x-uue") != NULL)
+    else if (_FP_stristr (localenv.ctenc, "x-uue") != NULL) {
       result->uudet = UU_ENCODED;
+      result->begin = result->end = 1;
+    }
+    else if (_FP_stristr (localenv.ctenc, "x-yenc") != NULL) {
+      result->uudet = YENC_ENCODED;
+      result->begin = result->end = 1;
+    }
     else if (_FP_stristr (localenv.ctenc, "quoted-printable") != NULL)
       result->uudet = QP_ENCODED;
     else if (_FP_stristr (localenv.ctenc, "7bit") != NULL ||
@@ -2450,8 +2538,14 @@ ScanPart (FILE *datei, char *fname, int *errcode)
 	result->uudet = QP_ENCODED;
       else if (_FP_stristr (localenv.ctenc, "base64") != NULL)
 	result->uudet = B64ENCODED;
-      else if (_FP_stristr (localenv.ctenc, "x-uue") != NULL)
+      else if (_FP_stristr (localenv.ctenc, "x-uue") != NULL) {
 	result->uudet = UU_ENCODED;
+	result->begin = result->end = 1;
+      }
+      else if (_FP_stristr (localenv.ctenc, "x-yenc") != NULL) {
+	result->uudet = YENC_ENCODED;
+	result->begin = result->end = 1;
+      }
       else if (_FP_stristr (localenv.ctenc, "7bit") != NULL ||
 	       _FP_stristr (localenv.ctenc, "8bit") != NULL)
 	result->uudet = PT_ENCODED;
@@ -2610,13 +2704,13 @@ ScanPart (FILE *datei, char *fname, int *errcode)
 	result->subject = _FP_strdup (sstate.envelope.subject);
     }
     result->partno = sstate.envelope.partno;
-    if (sstate.envelope.partno == 1)
-      result->begin = 1;
     result->maxpno = sstate.envelope.numparts;
     result->flags  = FL_PARTIAL | 
       ((res==1 || uu_fast_scanning) ? FL_PROPER : 0) |
 	((uu_fast_scanning) ? FL_TOEND : 0);
     result->mimeid = _FP_strdup (sstate.envelope.mimeid);
+    if (result->partno == 1)
+      result->begin = 1;
 
     if (uu_fast_scanning)
       result->length = progress.fsize - result->startpos;
@@ -2665,11 +2759,13 @@ ScanPart (FILE *datei, char *fname, int *errcode)
    * that we've had a Content-Disposition field, and we should probably
    * decode a plain-text segment with a filename.
    */
+
   if (sstate.isfolder && sstate.ismime &&
       sstate.mimestate == MS_BODY &&
       (_FP_stristr (sstate.envelope.ctenc, "quoted-printable") != NULL ||
        _FP_stristr (sstate.envelope.ctenc, "base64")           != NULL ||
        _FP_stristr (sstate.envelope.ctenc, "x-uue")            != NULL ||
+       _FP_stristr (sstate.envelope.ctenc, "x-yenc")           != NULL ||
        _FP_stristr (sstate.envelope.ctype, "message")          != NULL ||
        sstate.envelope.fname != NULL)) {
 
@@ -2687,8 +2783,13 @@ ScanPart (FILE *datei, char *fname, int *errcode)
       result->uudet = QP_ENCODED;
     else if (_FP_stristr (sstate.envelope.ctenc, "base64") != NULL)
       result->uudet = B64ENCODED;
-    else if (_FP_stristr (sstate.envelope.ctenc, "x-uue") != NULL)
+    else if (_FP_stristr (sstate.envelope.ctenc, "x-uue") != NULL) {
       result->uudet = UU_ENCODED;
+      result->begin = result->end = 1;
+    }
+    else if (_FP_stristr (sstate.envelope.ctenc, "x-yenc") != NULL) {
+      result->uudet = YENC_ENCODED;
+    }
     else if (_FP_stristr (sstate.envelope.ctenc, "7bit") != NULL ||
 	     _FP_stristr (sstate.envelope.ctenc, "8bit") != NULL)
       result->uudet = PT_ENCODED;
@@ -2916,7 +3017,8 @@ ScanPart (FILE *datei, char *fname, int *errcode)
 	while (*ptr1 && !isspace(*ptr1))
 	  ptr1++;
 	*ptr1 = '\0';
-	
+
+	sstate.envelope.mimevers = _FP_strdup ("1.0");
 	sstate.envelope.boundary = _FP_strdup (line+2);
 	
 	/*
@@ -2954,16 +3056,23 @@ ScanPart (FILE *datei, char *fname, int *errcode)
     UUkillfread   (result);
     return NULL;
   }
+
   /*
    * produce result
    */
+
   if (result->uudet == 0 && uu_handletext) {
     result->startpos = before;	/* display headers */
     result->uudet  = PT_ENCODED;
     result->partno = 1;
   }
 
-  if (sstate.envelope.fname) {
+  if (result->uudet == YENC_ENCODED && result->filename != NULL) {
+    /*
+     * prevent replacing the filename found on the =ybegin line
+     */
+  }
+  else if (sstate.envelope.fname) {
     _FP_free (result->filename);
     if ((result->filename = _FP_strdup (sstate.envelope.fname)) == NULL)
       *errcode = UURET_NOMEM;
@@ -2977,6 +3086,7 @@ ScanPart (FILE *datei, char *fname, int *errcode)
   else {
     /* assign a filename lateron */
   }
+
   if (result->subject == NULL) {
     if (sstate.envelope.subject)
       result->subject = _FP_strdup (sstate.envelope.subject);
diff --git a/goldlib/uulib/uustring.c b/goldlib/uulib/uustring.c
index dd99369..38b6c20 100644
--- a/goldlib/uulib/uustring.c
+++ b/goldlib/uulib/uustring.c
@@ -86,6 +86,10 @@ static stringmap messages[] = {
   { S_DECODE_CANCEL,    "Decode operation canceled" },
   { S_ENCODE_CANCEL,    "Encode operation canceled" },
   { S_SCAN_CANCEL,      "Scanning canceled" },
+  { S_SIZE_MISMATCH,    "%s: Decoded size (%ld) does not match expected size (%ld)" },
+  { S_PSIZE_MISMATCH,   "%s part %d: Decoded size (%ld) does not match expected size (%ld)" },
+  { S_CRC_MISMATCH,     "CRC32 mismatch in %s. Decoded file probably corrupt." },
+  { S_PCRC_MISMATCH,    "PCRC32 mismatch in %s part %d. Decoded file probably corrupt." },
 
   /* informational messages */
   { S_LOADED_PART,      "Loaded from %s: '%s' (%s): %s part %d %s %s %s" },
@@ -128,8 +132,8 @@ char *uuretcodes[] = {
  * Names of encoding types
  */
 
-char *codenames[7] = {
-  "", "UUdata", "Base64", "XXdata", "Binhex", "Text", "Text"
+char *codenames[8] = {
+  "", "UUdata", "Base64", "XXdata", "Binhex", "Text", "Text", "yEnc"
 };
 
 /*
diff --git a/goldlib/uulib/uustring.h b/goldlib/uulib/uustring.h
index 1531b7f..6c79256 100644
--- a/goldlib/uulib/uustring.h
+++ b/goldlib/uulib/uustring.h
@@ -1,4 +1,4 @@
-/* extracted from Id: uustring.c,v 1.6 2001/06/06 18:21:47 fp Exp  */
+/* extracted from Id: uustring.c,v 1.8 2002/03/11 09:15:47 fp Exp  */
 #define S_NOT_OPEN_SOURCE      1
 #define S_NOT_OPEN_TARGET      2
 #define S_NOT_OPEN_FILE        3
@@ -19,16 +19,20 @@
 #define S_DECODE_CANCEL       18
 #define S_ENCODE_CANCEL       19
 #define S_SCAN_CANCEL         20
-#define S_LOADED_PART         21
-#define S_NO_DATA_FOUND       22
-#define S_NO_BIN_FILE         23
-#define S_STRIPPED_SETUID     24
-#define S_DATA_SUSPICIOUS     25
-#define S_NO_TEMP_NAME        26
-#define S_BINHEX_SIZES        27
-#define S_BINHEX_BOTH         28
-#define S_SMERGE_MERGED       29
-#define S_MIME_NO_BOUNDARY    30
-#define S_MIME_B_NOT_FOUND    31
-#define S_MIME_MULTI_DEPTH    32
-#define S_MIME_PART_MULTI     33
+#define S_SIZE_MISMATCH       21
+#define S_PSIZE_MISMATCH      22
+#define S_CRC_MISMATCH        23
+#define S_PCRC_MISMATCH       24
+#define S_LOADED_PART         25
+#define S_NO_DATA_FOUND       26
+#define S_NO_BIN_FILE         27
+#define S_STRIPPED_SETUID     28
+#define S_DATA_SUSPICIOUS     29
+#define S_NO_TEMP_NAME        30
+#define S_BINHEX_SIZES        31
+#define S_BINHEX_BOTH         32
+#define S_SMERGE_MERGED       33
+#define S_MIME_NO_BOUNDARY    34
+#define S_MIME_B_NOT_FOUND    35
+#define S_MIME_MULTI_DEPTH    36
+#define S_MIME_PART_MULTI     37