uuencode fixes

This commit is contained in:
Alexander S. Aganichev 2001-11-01 17:20:18 +00:00
parent 9d58bafa3e
commit 01da006468
14 changed files with 814 additions and 238 deletions

View File

@ -12,6 +12,10 @@ ______________________________________________________________________
Notes for GoldED+ 1.1.5, /snapshot/
______________________________________________________________________
! Updated uulib to the latest version. Few bugs fixed. Unordered
UU encode now should be processed more accurately than with original
library.
- Fixed improper charset conversion when replying on message without
charset between areas with different Xlatimport.

View File

@ -1,7 +1,7 @@
# -*- makefile -*-
VERSION=0.5
PATCH=13
PATCH=15
TOP=../..
TARGET=uulib

View File

@ -1,9 +1,8 @@
/*
* fptools.c, some helper functions for getcgi.c and uu(en|de)view
*
* Distributed by the GNU General Public License. Use and be happy.
* Read http://www.uni-frankfurt.de/~fp/Tools/Getcgi.html for more
* information. fp@informatik.uni-frankfurt.de
* Distributed under the terms of the GNU General Public License.
* Use and be happy.
*/
#ifdef HAVE_CONFIG_H

View File

@ -1,9 +1,8 @@
/*
* fptools.c, some helper functions for getcgi.c and uu(en|de)view
*
* Distributed by the GNU General Public License. Use and be happy.
* Read http://www.uni-frankfurt.de/~fp/Tools/Getcgi.html for more
* information. fp@informatik.uni-frankfurt.de
* Distributed under the terms of the GNU General Public License.
* Use and be happy.
*/
/*

View File

@ -1,7 +1,7 @@
/*
* This file is part of uudeview, the simple and friendly multi-part multi-
* file uudecoder program (c) 1994 by Frank Pilhofer. The author may be
* contacted by his email address, fp@informatik.uni-frankfurt.de
* file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may
* be contacted at fp@fpx.de
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -14,7 +14,6 @@
* GNU General Public License for more details.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@ -847,7 +846,7 @@ UUPreProcessPart (fileread *data, int *ret)
}
lastvalid = 0;
}
else if (lastvalid && data->uudet == lastenc) {
else if (lastvalid && data->uudet == lastenc && result->partno <= 0) {
result->subfname = _FP_strdup (uucheck_lastname);
result->partno = ++lastpart;
@ -857,7 +856,10 @@ UUPreProcessPart (fileread *data, int *ret)
if (data->end || (data->partno && data->partno == data->maxpno))
lastvalid = 0;
}
else {
else if (data->partno != -1 && result->filename) {
result->subfname = _FP_strdup (result->filename);
}
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.
@ -1460,9 +1462,3 @@ UUCheckGlobalList (void)
return UUGlobalFileList;
}
/*****************************************************************************
+ Frank Pilhofer fp@informatik.uni-frankfurt.de +
+---------------------------------------------------------------------------+
| Department of Computer Sciences * University of Frankfurt / Main, Germany |
*****************************************************************************/

View File

@ -1,7 +1,7 @@
/*
* This file is part of uudeview, the simple and friendly multi-part multi-
* file uudecoder program (c) 1994 by Frank Pilhofer. The author may be
* contacted by his email address, fp@informatik.uni-frankfurt.de
* file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may
* be contacted at fp@fpx.de
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -104,6 +104,8 @@
#define UUOPT_PREAMB (17) /* handle Mime preambles/epilogues */
#define UUOPT_TINYB64 (18) /* detect short B64 outside of Mime */
#define UUOPT_ENCEXT (19) /* extension for single-part encoded files */
#define UUOPT_REMOVE (20) /* remove input files after decoding */
#define UUOPT_MOREMIME (21) /* strict MIME adherence */
/*
* Code for the "action" in the progress structure
@ -239,6 +241,19 @@ int UUEXPORT UUE_PrepPartial _ANSI_ARGS_((FILE *, FILE *,
char *, int,
int, long, long, char *,
char *, char *, int));
int UUEXPORT UUE_PrepSingleExt _ANSI_ARGS_((FILE *, FILE *,
char *, int,
char *, int,
char *, char *,
char *, char *,
int));
int UUEXPORT UUE_PrepPartialExt _ANSI_ARGS_((FILE *, FILE *,
char *, int,
char *, int,
int, long, long, char *,
char *, char *, char *,
int));
#ifdef __cplusplus
}
#endif

View File

@ -1,7 +1,7 @@
/*
* This file is part of uudeview, the simple and friendly multi-part multi-
* file uudecoder program (c) 1994 by Frank Pilhofer. The author may be
* contacted by his email address, fp@informatik.uni-frankfurt.de
* file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may
* be contacted at fp@fpx.de
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -98,9 +98,9 @@ char * uuencode_id = "$Id$";
*/
#ifdef EOLSTRING
static unsigned char *eolstring = (unsigned char *) EOLSTRING;
static char *eolstring = (char *) EOLSTRING;
#else
static unsigned char *eolstring = (unsigned char *) "\012";
static char *eolstring = (char *) "\012";
#endif
/*
@ -114,6 +114,8 @@ static unsigned char *eolstring = (unsigned char *) "\012";
#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")
/*
@ -163,7 +165,12 @@ unsigned char BHEncodeTable[64] = {
'S', 'T', 'U', 'V', 'X', 'Y', 'Z', '[',
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'h',
'i', 'j', 'k', 'l', 'm', 'p', 'q', 'r'
};
};
unsigned char HexEncodeTable[16] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
typedef struct {
char *extension;
@ -191,7 +198,7 @@ static mimemap mimetable[] = {
{ "mpeg", "video/mpeg" }, /* Motion Picture Expert Group */
{ "mpg", "video/mpeg" },
{ "mp2", "video/mpeg" }, /* dito, MPEG-2 encoded files */
{ "mp3", "video/mpeg" }, /* dito, MPEG-3 encoded files */
{ "mp3", "audio/mpeg" }, /* dito, MPEG-3 encoded files */
{ "ps", "application/postscript" }, /* Postscript Language */
{ "zip", "application/zip" }, /* ZIP archive */
{ "doc", "application/msword"},/* assume Microsoft Word */
@ -243,12 +250,161 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile)
size_t llen;
if (outfile==NULL || infile==NULL ||
(encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED)) {
(encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&&
encoding!=PT_ENCODED&&encoding!=QP_ENCODED)) {
UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
uustring (S_PARM_CHECK), "UUEncodeStream()");
return UURET_ILLVAL;
}
/*
* Special handling for plain text and quoted printable. Text is
* read line oriented.
*/
if (encoding == PT_ENCODED || encoding == QP_ENCODED) {
while (!feof (infile) && (linperfile <= 0 || line < linperfile)) {
if (_FP_fgets ((char *)itemp, 255, infile) == NULL) {
break;
}
itemp[255] = '\0';
count = strlen ((char *)itemp);
llen = 0;
optr = otemp;
/*
* Busy Callback
*/
if (UUBUSYPOLL(ftell(infile)-progress.foffset,progress.fsize)) {
UUMessage (uuencode_id, __LINE__, UUMSG_NOTE,
uustring (S_ENCODE_CANCEL));
return UURET_CANCEL;
}
if (encoding == PT_ENCODED) {
/*
* If there is a line feed, replace by eolstring
*/
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)) {
return UURET_IOERR;
}
}
else {
if (fwrite (itemp, 1, count, outfile) != llen) {
return UURET_IOERR;
}
}
}
else if (encoding == QP_ENCODED) {
for (index=0; index<count; index++) {
if (llen == 0 && itemp[index] == '.') {
/*
* Special rule: encode '.' at the beginning of a line, so
* that some mailers aren't confused.
*/
*optr++ = '=';
*optr++ = HexEncodeTable[itemp[index] >> 4];
*optr++ = HexEncodeTable[itemp[index] & 0x0f];
llen += 3;
}
else if ((itemp[index] >= 33 && itemp[index] <= 60) ||
(itemp[index] >= 62 && itemp[index] <= 126) ||
itemp[index] == 9 || itemp[index] == 32) {
*optr++ = itemp[index];
llen++;
}
else if (itemp[index] == '\n') {
/*
* If the last character before EOL was a space or tab,
* we must encode it. If llen > 74, there's no space to do
* that, so generate a soft line break instead.
*/
if (index>0 && (itemp[index-1] == 9 || itemp[index-1] == 32)) {
*(optr-1) = '=';
if (llen <= 74) {
*optr++ = HexEncodeTable[itemp[index-1] >> 4];
*optr++ = HexEncodeTable[itemp[index-1] & 0x0f];
llen += 2;
}
}
if (fwrite (otemp, 1, llen, outfile) != llen ||
fwrite (eolstring, 1,
strlen(eolstring), outfile) != strlen (eolstring)) {
return UURET_IOERR;
}
/*
* Fix the soft line break condition from above
*/
if (index>0 && (itemp[index-1] == 9 || itemp[index-1] == 32) &&
*(optr-1) == '=') {
otemp[0] = '=';
otemp[1] = HexEncodeTable[itemp[index-1] >> 4];
otemp[2] = HexEncodeTable[itemp[index-1] & 0x0f];
if (fwrite (otemp, 1, 3, outfile) != 3 ||
fwrite (eolstring, 1,
strlen(eolstring), outfile) != strlen (eolstring)) {
return UURET_IOERR;
}
}
optr = otemp;
llen = 0;
}
else {
*optr++ = '=';
*optr++ = HexEncodeTable[itemp[index] >> 4];
*optr++ = HexEncodeTable[itemp[index] & 0x0f];
llen += 3;
}
/*
* Lines must be shorter than 76 characters (not counting CRLF).
* If the line grows longer than that, we must include a soft
* line break.
*/
if (itemp[index+1] != 0 && itemp[index+1] != '\n' &&
(llen >= 75 ||
(!((itemp[index+1] >= 33 && itemp[index+1] <= 60) ||
(itemp[index+1] >= 62 && itemp[index+1] <= 126)) &&
llen >= 73))) {
*optr++ = '=';
llen++;
if (fwrite (otemp, 1, llen, outfile) != llen ||
fwrite (eolstring, 1,
strlen(eolstring), outfile) != strlen (eolstring)) {
return UURET_IOERR;
}
optr = otemp;
llen = 0;
}
}
}
line++;
}
return UURET_OK;
}
/*
* Handling for binary encodings
*/
/*
* select charset
@ -258,7 +414,7 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile)
if (table==NULL || bpl[encoding]==0) {
UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
uustring (S_PARM_CHECK), "UUEncodeStream()");
uustring (S_PARM_CHECK), "UUEncodeStream()");
return UURET_ILLVAL;
}
@ -269,6 +425,7 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile)
else if (ferror (infile))
return UURET_IOERR;
}
optr = otemp;
llen = 0;
@ -285,65 +442,76 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile)
/*
* for UU and XX, encode the number of bytes as first character
*/
if (encoding == UU_ENCODED || encoding == XX_ENCODED) {
*optr++ = table[count];
llen++;
}
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];
/*
* 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];
}
/*
* 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 (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;
}
}
}
/*
* 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 (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;
}
}
/*
* end of line
*/
tptr = eolstring;
tptr = (unsigned char *) eolstring;
while (*tptr)
*optr++ = *tptr++;
*optr++ = '\0';
llen += strlen ((char *) eolstring);
llen += strlen (eolstring);
if (fwrite (otemp, 1, llen, outfile) != llen)
return UURET_IOERR;
@ -370,7 +538,8 @@ UUEncodeMulti (FILE *outfile, FILE *infile, char *infname, int encoding,
if (outfile==NULL ||
(infile == NULL && infname==NULL) ||
(outfname==NULL && infname==NULL) ||
(encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED)) {
(encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&&
encoding!=PT_ENCODED&&encoding!=QP_ENCODED)) {
UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
uustring (S_PARM_CHECK), "UUEncodeMulti()");
return UURET_ILLVAL;
@ -430,6 +599,11 @@ UUEncodeMulti (FILE *outfile, FILE *infile, char *infname, int encoding,
mimetype = miter->mimetype;
}
}
if (mimetype == NULL && (encoding == PT_ENCODED || encoding == QP_ENCODED)) {
mimetype = "text/plain";
}
/*
* print sub-header
*/
@ -497,7 +671,8 @@ UUEncodePartial (FILE *outfile, FILE *infile,
if ((outfname==NULL&&infname==NULL) || partno<=0 ||
(infile == NULL&&infname==NULL) || outfile==NULL ||
(encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED)) {
(encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&&
encoding!=PT_ENCODED&&encoding!=QP_ENCODED)) {
UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
uustring (S_PARM_CHECK), "UUEncodePartial()");
return UURET_ILLVAL;
@ -574,6 +749,11 @@ UUEncodePartial (FILE *outfile, FILE *infile,
mimetype = miter->mimetype;
}
}
if (mimetype == NULL && (encoding==PT_ENCODED || encoding==QP_ENCODED)) {
mimetype = "text/plain";
}
/*
* print sub-header
*/
@ -639,10 +819,14 @@ UUEncodePartial (FILE *outfile, FILE *infile,
eolstring);
fprintf (outfile, "end%s", eolstring);
}
/*
* empty line at end does no harm
*/
fprintf (outfile, "%s", eolstring);
if (encoding != PT_ENCODED && encoding != QP_ENCODED) {
fprintf (outfile, "%s", eolstring);
}
if (infile==NULL) {
if (res != UURET_OK) {
@ -682,7 +866,8 @@ UUEncodeToStream (FILE *outfile, FILE *infile,
if (outfile==NULL ||
(infile == NULL&&infname==NULL) ||
(outfname==NULL&&infname==NULL) ||
(encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED)) {
(encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&&
encoding!=PT_ENCODED&&encoding!=QP_ENCODED)) {
UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
uustring (S_PARM_CHECK), "UUEncodeToStream()");
return UURET_ILLVAL;
@ -778,7 +963,8 @@ UUEncodeToFile (FILE *infile, char *infname, int encoding,
if ((diskname==NULL&&infname==NULL) ||
(outfname==NULL&&infname==NULL) || (infile==NULL&&infname==NULL) ||
(encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED)) {
(encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&&
encoding!=PT_ENCODED&&encoding!=QP_ENCODED)) {
UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
uustring (S_PARM_CHECK), "UUEncodeToFile()");
return UURET_ILLVAL;
@ -1012,6 +1198,22 @@ UUE_PrepSingle (FILE *outfile, FILE *infile,
char *outfname, int filemode,
char *destination, char *from,
char *subject, int isemail)
{
return UUE_PrepSingleExt (outfile, infile,
infname, encoding,
outfname, filemode,
destination, from,
subject, NULL,
isemail);
}
int UUEXPORT
UUE_PrepSingleExt (FILE *outfile, FILE *infile,
char *infname, int encoding,
char *outfname, int filemode,
char *destination, char *from,
char *subject, char *replyto,
int isemail)
{
mimemap *miter=mimetable;
char *subline, *oname;
@ -1019,7 +1221,8 @@ UUE_PrepSingle (FILE *outfile, FILE *infile,
int res, len;
if ((outfname==NULL&&infname==NULL) || (infile==NULL&&infname==NULL) ||
(encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED)) {
(encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&&
encoding!=PT_ENCODED&&encoding!=QP_ENCODED)) {
UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
uustring (S_PARM_CHECK), "UUE_PrepSingle()");
return UURET_ILLVAL;
@ -1036,6 +1239,10 @@ UUE_PrepSingle (FILE *outfile, FILE *infile,
else
mimetype = NULL;
if (mimetype == NULL && (encoding == PT_ENCODED || encoding == QP_ENCODED)) {
mimetype = "text/plain";
}
if ((subline = (char *) malloc (len)) == NULL) {
UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
uustring (S_OUT_OF_MEMORY), len);
@ -1047,8 +1254,6 @@ UUE_PrepSingle (FILE *outfile, FILE *infile,
else
sprintf (subline, "[ %s ] (001/001)", oname);
fprintf (outfile, "Subject: %s%s", subline, eolstring);
if (from) {
fprintf (outfile, "From: %s%s", from, eolstring);
}
@ -1057,6 +1262,13 @@ UUE_PrepSingle (FILE *outfile, FILE *infile,
(isemail)?"To":"Newsgroups",
destination, eolstring);
}
fprintf (outfile, "Subject: %s%s", subline, eolstring);
if (replyto) {
fprintf (outfile, "Reply-To: %s%s", replyto, eolstring);
}
fprintf (outfile, "MIME-Version: 1.0%s", eolstring);
fprintf (outfile, "Content-Type: %s; name=\"%s\"%s",
(mimetype)?mimetype:"Application/Octet-Stream",
@ -1080,6 +1292,24 @@ UUE_PrepPartial (FILE *outfile, FILE *infile,
int partno, long linperfile, long filesize,
char *destination, char *from, char *subject,
int isemail)
{
return UUE_PrepPartialExt (outfile, infile,
infname, encoding,
outfname, filemode,
partno, linperfile, filesize,
destination,
from, subject, NULL,
isemail);
}
int UUEXPORT
UUE_PrepPartialExt (FILE *outfile, FILE *infile,
char *infname, int encoding,
char *outfname, int filemode,
int partno, long linperfile, long filesize,
char *destination,
char *from, char *subject, char *replyto,
int isemail)
{
static int numparts, themode;
static char mimeid[64];
@ -1090,7 +1320,8 @@ UUE_PrepPartial (FILE *outfile, FILE *infile,
int res, len;
if ((outfname==NULL&&infname==NULL) || (infile==NULL&&infname==NULL) ||
(encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED)) {
(encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&&
encoding!=PT_ENCODED&&encoding!=QP_ENCODED)) {
UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
uustring (S_PARM_CHECK), "UUE_PrepPartial()");
return UURET_ILLVAL;
@ -1163,9 +1394,9 @@ UUE_PrepPartial (FILE *outfile, FILE *infile,
if (numparts == 1) {
if (infile==NULL) fclose (theifile);
return UUE_PrepSingle (outfile, infile, infname, encoding,
outfname, filemode, destination,
from, subject, isemail);
return UUE_PrepSingleExt (outfile, infile, infname, encoding,
outfname, filemode, destination,
from, subject, replyto, isemail);
}
/*
@ -1190,16 +1421,22 @@ UUE_PrepPartial (FILE *outfile, FILE *infile,
sprintf (subline, "[ %s ] (%03d/%03d)",
oname, partno, numparts);
fprintf (outfile, "Subject: %s%s", subline, eolstring);
if (from) {
fprintf (outfile, "From: %s%s", from, eolstring);
}
if (destination) {
fprintf (outfile, "%s: %s%s",
(isemail)?"To":"Newsgroups",
destination, eolstring);
}
fprintf (outfile, "Subject: %s%s", subline, eolstring);
if (replyto) {
fprintf (outfile, "Reply-To: %s%s", replyto, eolstring);
}
fprintf (outfile, "MIME-Version: 1.0%s", eolstring);
fprintf (outfile, "Content-Type: Message/Partial; number=%d; total=%d;%s",
partno, numparts, eolstring);

View File

@ -1,7 +1,7 @@
/*
* This file is part of uudeview, the simple and friendly multi-part multi-
* file uudecoder program (c) 1994 by Frank Pilhofer. The author may be
* contacted by his email address, fp@informatik.uni-frankfurt.de
* file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may
* be contacted at fp@fpx.de
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -204,6 +204,8 @@ extern int uu_headercount;
extern int uu_usepreamble;
extern int uu_handletext;
extern int uu_tinyb64;
extern int uu_remove_input;
extern int uu_more_mime;
extern char *uusavepath;
extern char *uuencodeext;

View File

@ -1,7 +1,7 @@
/*
* This file is part of uudeview, the simple and friendly multi-part multi-
* file uudecoder program (c) 1994 by Frank Pilhofer. The author may be
* contacted by his email address, fp@informatik.uni-frankfurt.de
* file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may
* be contacted at fp@fpx.de
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -72,7 +72,7 @@
#endif
/* to get open() in Windows */
#if defined(HAVE_IO_H) && defined(__MINGW32__)
#ifdef HAVE_IO_H
#include <io.h>
#endif
@ -141,6 +141,8 @@ int uu_ignmode = 0; /* ignore the original file mode */
int uu_handletext = 0; /* do we want text/plain messages */
int uu_usepreamble = 0; /* do we want Mime preambles/epilogues */
int uu_tinyb64 = 0; /* detect short B64 outside of MIME */
int uu_remove_input = 0; /* remove input files after decoding */
int uu_more_mime = 0; /* strictly adhere to MIME headers */
headercount hlcount = {
3, /* restarting after a MIME body */
@ -229,10 +231,10 @@ static allomap toallocate[] = {
{ &uucheck_lastname, 256 }, /* from uucheck.c */
{ &uucheck_tempname, 256 },
{ &uuestr_itemp, 256 }, /* from uuencode.c:UUEncodeStream() */
{ &uuestr_otemp, 256 },
{ &uuestr_otemp, 1024 },
{ &uulib_msgstring, 1024 }, /* from uulib.c:UUMessage() */
{ &uuncdl_fulline, 256 }, /* from uunconc.c:UUDecodeLine() */
{ &uuncdp_oline, 512 }, /* from uunconc.c:UUDecodePart() */
{ &uuncdl_fulline, 260 }, /* from uunconc.c:UUDecodeLine() */
{ &uuncdp_oline, 1024 }, /* from uunconc.c:UUDecodePart() */
{ &uunconc_UUxlat, 256 * sizeof (int) }, /* from uunconc.c:toplevel */
{ &uunconc_UUxlen, 64 * sizeof (int) },
{ &uunconc_B64xlat, 256 * sizeof (int) },
@ -487,6 +489,14 @@ UUGetOption (int option, int *ivalue, char *cvalue, int clength)
_FP_strncpy (cvalue, uuencodeext, clength);
result = 0;
break;
case UUOPT_REMOVE:
if (ivalue) *ivalue = uu_remove_input;
result = uu_remove_input;
break;
case UUOPT_MOREMIME:
if (ivalue) *ivalue = uu_more_mime;
result = uu_more_mime;
break;
default:
return -1;
}
@ -541,6 +551,12 @@ UUSetOption (int option, int ivalue, char *cvalue)
_FP_free (uuencodeext);
uuencodeext = _FP_strdup (cvalue);
break;
case UUOPT_REMOVE:
uu_remove_input = ivalue;
break;
case UUOPT_MOREMIME:
uu_more_mime = ivalue;
break;
default:
return UURET_ILLVAL;
}
@ -733,6 +749,7 @@ UULoadFile (char *filename, char *fileid, int delflag)
}
if ((loaded->uudet == QP_ENCODED || loaded->uudet == PT_ENCODED) &&
(loaded->filename == NULL || *(loaded->filename) == '\0') &&
!uu_handletext && (loaded->flags&FL_PARTIAL)==0) {
/*
* Don't want text
@ -1147,14 +1164,14 @@ int UUEXPORT
UUCleanUp (void)
{
itbd *iter=ftodel, *ptr;
uulist *liter;
uufile *fiter;
allomap *aiter;
UUkilllist (UUGlobalFileList);
UUGlobalFileList = NULL;
/*
* delete input files
* delete temporary input files (such as the copy of stdin)
*/
while (iter) {
if (unlink (iter->fname)) {
UUMessage (uulib_id, __LINE__, UUMSG_WARNING,
@ -1166,8 +1183,36 @@ UUCleanUp (void)
iter = iter->NEXT;
_FP_free (ptr);
}
ftodel = NULL;
/*
* Delete input files after successful decoding
*/
if (uu_remove_input) {
liter = UUGlobalFileList;
while (liter) {
if (liter->state & UUFILE_DECODED) {
fiter = liter->thisfile;
while (fiter) {
if (fiter->data && fiter->data->sfname) {
/*
* Error code ignored. We might want to delete a file multiple
* times
*/
unlink (fiter->data->sfname);
}
fiter = fiter->NEXT;
}
}
liter = liter->NEXT;
}
}
UUkilllist (UUGlobalFileList);
UUGlobalFileList = NULL;
_FP_free (uusavepath);
_FP_free (uuencodeext);
_FP_free (sstate.source);

View File

@ -1,7 +1,7 @@
/*
* This file is part of uudeview, the simple and friendly multi-part multi-
* file uudecoder program (c) 1994 by Frank Pilhofer. The author may be
* contacted by his email address, fp@informatik.uni-frankfurt.de
* file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may
* be contacted at fp@fpx.de
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -165,7 +165,7 @@ UUInitConc (void)
/* prepare line length table */
UUxlen[0] = 1;
for(i = 1, j = 5; i <= 60; i += 3, j += 4)
for(i = 1, j = 5; i <= 61; i += 3, j += 4)
UUxlen[i] = UUxlen[i+1] = UUxlen[i+2] = j;
/* prepare other tables */
@ -243,11 +243,10 @@ UUNetscapeCollapse (char *string)
*/
while (*p1) {
if (*p1 == '&') {
if (_FP_strnicmp (p1, "&amp;", 5) == 0) { p1+=5; *p2++='&'; }
else if (_FP_strnicmp (p1, "&lt;", 4) == 0) { p1+=4; *p2++='<'; }
else if (_FP_strnicmp (p1, "&gt;", 4) == 0) { p1+=4; *p2++='>'; }
if (_FP_strnicmp (p1, "&amp;", 5) == 0) { p1+=5; *p2++='&'; res=1; }
else if (_FP_strnicmp (p1, "&lt;", 4) == 0) { p1+=4; *p2++='<'; res=1; }
else if (_FP_strnicmp (p1, "&gt;", 4) == 0) { p1+=4; *p2++='>'; res=1; }
else *p2++ = *p1++;
res = 1;
}
else *p2++ = *p1++;
}
@ -298,7 +297,7 @@ UUValidData (char *ptr, int encoding, int *bhflag)
int i=0, j, len=0, suspicious=0, flag=0;
char *s = ptr;
if ((s == NULL) || (*s & 0x80)) {
if ((s == NULL) || !(iscntrl(ACAST(*s)) || isascii(ACAST(*s)))) {
return(0); /* bad string */
}
@ -382,7 +381,8 @@ UUValidData (char *ptr, int encoding, int *bhflag)
*/
while (len--) {
if ((*s & 0x80) || (B64xlat[ACAST(*s)] == -1 && *s != '=')) {
if (!(iscntrl(ACAST(*s)) || isascii(ACAST(*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++==' ') {
@ -450,8 +450,10 @@ UUValidData (char *ptr, int encoding, int *bhflag)
* evaluated if the first character is lowercase, which really shouldn't
* be in uuencoded text.
*/
if (len != j &&
!(*ptr != 'M' && *ptr != 'h' && len > j && len <= UUxlen[UUxlat['M']])) {
if (len != j &&
((ptr[0] == '-' && ptr[1] == '-' && strstr(ptr,"part")!=NULL) ||
!(*ptr != 'M' && *ptr != 'h' &&
len > j && len <= UUxlen[UUxlat['M']]))) {
if (encoding==UU_ENCODED) return 0;
goto _t_XX; /* bad length */
}
@ -472,7 +474,8 @@ UUValidData (char *ptr, int encoding, int *bhflag)
}
while (len--) {
if ((*s & 0x80) || UUxlat[ACAST(*s++)] < 0) {
if (!(iscntrl(ACAST(*s)) || isascii(ACAST(*s))) ||
UUxlat[ACAST(*s++)] < 0) {
if (encoding==UU_ENCODED) return 0;
goto _t_XX; /* bad code character */
}
@ -512,7 +515,8 @@ UUValidData (char *ptr, int encoding, int *bhflag)
return 0; /* bad length */
while(len--) {
if((*s & 0x80) || XXxlat[ACAST(*s++)] < 0) {
if (!(iscntrl(ACAST(*s)) || isascii(ACAST(*s))) ||
XXxlat[ACAST(*s++)] < 0) {
return 0; /* bad code character */
}
}
@ -861,9 +865,8 @@ UUDecodePT (FILE *datain, FILE *dataout, int *state,
* So if the part ends here, don't print a line break"
*/
if ((*ptr == '\012' || *ptr == '\015') &&
(!feof (datain) &&
(ftell(datain)<maxpos || flags&FL_TOEND || flags&FL_PARTIAL ||
(!(flags&FL_PROPER) && uu_fast_scanning)))) {
(ftell(datain)<maxpos || flags&FL_TOEND || flags&FL_PARTIAL ||
!boundary || (!(flags&FL_PROPER) && uu_fast_scanning))) {
*ptr = '\0';
fprintf (dataout, "%s\n", line);
}
@ -988,6 +991,7 @@ UUDecodePart (FILE *datain, FILE *dataout, int *state,
if (*state == BEGIN) {
if (strncmp (line, "begin ", 6) == 0 ||
strncmp (line, "section ", 8) == 0 ||
_FP_strnicmp (line, "<pre>begin ", 11) == 0) { /* for LYNX */
*state = DATA;
continue;
@ -1032,8 +1036,9 @@ UUDecodePart (FILE *datain, FILE *dataout, int *state,
}
if (vflag == method) {
if (tf) {
if (tf || (method == UU_ENCODED || method == XX_ENCODED)) {
count = UUDecodeLine (line, oline, method);
tf = 1;
vlc++; lc[1]++;
}
else if (tc == 3) {
@ -1151,7 +1156,7 @@ UUDecode (uulist *data)
if (data->state & UUFILE_NOBEGIN && !uu_desperate)
return UURET_NODATA;
if (data->uudet == QP_ENCODED || data->uudet == PT_ENCODED)
if (data->uudet == PT_ENCODED)
mode = "wt"; /* open text files in text mode */
else
mode = "wb"; /* otherwise in binary */

View File

@ -1,7 +1,7 @@
/*
* This file is part of uudeview, the simple and friendly multi-part multi-
* file uudecoder program (c) 1994 by Frank Pilhofer. The author may be
* contacted by his email address, fp@informatik.uni-frankfurt.de
* file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may
* be contacted at fp@fpx.de
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -126,12 +126,6 @@ char *uuscan_sdbhds1;
char *uuscan_sdbhds2;
char *uuscan_spline;
/*
* If this is changed to define, some workarounds for broken files are
* disabled
*/
#undef MORE_MIME
/*
* Macro: print cancellation message in UUScanPart
*/
@ -338,32 +332,35 @@ ParseHeader (headers *theheaders, char *line)
if (line == NULL)
return theheaders;
value = NULL; delimit = 0;
if (_FP_strnicmp (line, "From:", 5) == 0) {
if (theheaders->from) return theheaders;
variable = &theheaders->from;
value = line+5;
delimit = 0;
}
else if (_FP_strnicmp (line, "Subject:", 8) == 0) {
if (theheaders->subject) return theheaders;
variable = &theheaders->subject;
value = line+8;
delimit = 0;
}
else if (_FP_strnicmp (line, "To:", 3) == 0) {
if (theheaders->rcpt) return theheaders;
variable = &theheaders->rcpt;
value = line+3;
delimit = 0;
}
else if (_FP_strnicmp (line, "Date:", 5) == 0) {
if (theheaders->date) return theheaders;
variable = &theheaders->date;
value = line+5;
delimit = 0;
}
else if (_FP_strnicmp (line, "Mime-Version:", 13) == 0) {
if (theheaders->mimevers) return theheaders;
variable = &theheaders->mimevers;
value = line+13;
delimit = 0;
}
else if (_FP_strnicmp (line, "Content-Type:", 13) == 0) {
if (theheaders->ctype) return theheaders;
@ -420,12 +417,16 @@ ParseHeader (headers *theheaders, char *line)
}
}
variable = NULL;
value = NULL;
delimit = 0;
}
else {
/*
* nothing interesting
*/
variable = NULL;
value = NULL;
delimit = 0;
}
/*
@ -519,11 +520,13 @@ ScanData (FILE *datei, char *fname, int *errcode,
{
char *line=uuscan_sdline, *bhds1=uuscan_sdbhds1, *bhds2=uuscan_sdbhds2;
static char *ptr, *p2, *p3=NULL, *bhdsp, bhl;
int isb64[10], isuue[10], isxxe[10], isbhx[10], iscnt;
int cbb64, cbuue, cbxxe, cbbhx;
int bhflag=0, vflag, haddh=0, hadct=0;
int bhrpc=0, bhnf=0, c, hcount, lcount, blen;
int bhrpc=0, bhnf=0, c, hcount, lcount, blen=0;
int encoding=0, dflag=0, ctline=42;
int dontcare=0, hadnl=0;
long preheaders = 0, oldposition;
long preheaders=0, oldposition;
size_t dcc, bhopc;
*errcode = UURET_OK;
@ -536,7 +539,14 @@ ScanData (FILE *datei, char *fname, int *errcode,
result->startpos = ftell (datei);
hcount = lcount = 0;
blen = (boundary) ? strlen (boundary) : 0;
for (iscnt=0; iscnt<10; iscnt++) {
isb64[iscnt] = isuue[iscnt] = isxxe[iscnt] = isbhx[iscnt] = 0;
}
iscnt = 0;
if (boundary)
blen = strlen (boundary);
while (!feof (datei)) {
oldposition = ftell (datei);
@ -547,15 +557,10 @@ ScanData (FILE *datei, char *fname, int *errcode,
line[255] = '\0'; /* For Safety of string functions */
if (IsLineEmpty (line)) { /* line empty? */
hcount = 0;
hadnl = 1;
continue; /* then ignore */
}
/*
* Make Busy Polls
*/
if (UUBUSYPOLL(ftell(datei),progress.fsize)) {
UUMessage (uuscan_id, __LINE__, UUMSG_NOTE,
uustring (S_SCAN_CANCEL));
@ -563,6 +568,12 @@ ScanData (FILE *datei, char *fname, int *errcode,
break;
}
if (IsLineEmpty (line)) { /* line empty? */
hcount = 0;
hadnl = 1;
continue; /* then ignore */
}
if (checkheaders) {
if (IsKnownHeader (line)) {
(void) ScanHeaderLine (datei, line);
@ -606,6 +617,7 @@ ScanData (FILE *datei, char *fname, int *errcode,
else {
dontcare=0;
}
if (boundary != NULL &&
line[0] == '-' && line[1] == '-' &&
strncmp (line+2, boundary, blen) == 0) {
@ -629,8 +641,9 @@ ScanData (FILE *datei, char *fname, int *errcode,
if (strncmp (line, "begin ", 6) == 0 ||
_FP_strnicmp (line, "<pre>begin ", 11) == 0) {
if (result->begin || result->end ||
result->uudet == B64ENCODED || result->uudet == BH_ENCODED) {
if ((result->begin || result->end ||
result->uudet == B64ENCODED ||
result->uudet == BH_ENCODED) && !uu_more_mime) {
fseek (datei, oldposition, SEEK_SET);
break;
}
@ -673,15 +686,20 @@ ScanData (FILE *datei, char *fname, int *errcode,
hadnl = 0;
/*
* Detect a UUDeview-Style header
* Detect a UUDeview/UUCODE-Style headers
*/
if (_FP_strnicmp (line, "_=_ Part ", 9) == 0) {
if (_FP_strnicmp (line, "_=_ Part ", 9) == 0 ||
_FP_strnicmp (line, "section ", 8) == 0) {
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++;
@ -708,7 +726,7 @@ 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) {
if (boundary == NULL && !ismime && !uu_more_mime) {
if (_FP_strnicmp (line, "Content-Type", 12) == 0 ||
_FP_strnicmp (line, "X-Orcl-Content-Type", 19) == 0) {
/*
@ -796,7 +814,7 @@ ScanData (FILE *datei, char *fname, int *errcode,
/*
* Handling for very short Base64 files.
*/
if (uu_tinyb64) {
if (uu_tinyb64 && !ismime && !uu_more_mime) {
if (line[0] == '-' && line[1] == '-') {
if (dflag && (encoding==B64ENCODED || result->uudet==B64ENCODED)) {
if (encoding==B64ENCODED && result->uudet==0 && (haddh||hadct)) {
@ -811,34 +829,76 @@ ScanData (FILE *datei, char *fname, int *errcode,
}
} /* end of reduced MIME handling */
/*
* If we're in "freestyle" mode, have not encountered anything
* interesting yet, and stumble upon something that looks like
* a boundary, followed by a Content-* line, try to use it.
*/
if (boundary == NULL && !ismime && !uu_more_mime && dflag <= 1 &&
line[0] == '-' && line[1] == '-' && strlen(line+2)>10 &&
(((ptr = _FP_strrstr (line+2, "--")) == NULL) ||
(*(ptr+2) != '\012' && *(ptr+2) != '\015')) &&
_FP_strstr (line+2, "_=_") != NULL) {
if (_FP_fgets (line, 255, datei) == NULL) {
break;
}
if (_FP_strnicmp (line, "Content-", 8) == 0) {
/*
* Okay, let's do it. This breaks out of ScanData. ScanPart will
* recognize the boundary on the next call and use it.
*/
fseek (datei, oldposition, SEEK_SET);
break;
}
}
/*
* if we haven't yet found anything encoded, try to find something
*/
#if 0
if (!(result->uudet)) {
#endif
/*
* Netscape-Repair code is the same as in uunconc.c
*/
if ((vflag = UUValidData (line, 0, &bhflag)) == 0)
if ((vflag = UUValidData (line, 0, &bhflag)) == 0 && !ismime)
vflag = UURepairData (datei, line, 0, &bhflag);
/*
* In a few cases, we might mistake uu or xx-encoded data for
* Base64, because their alphabets overlap (XX and Base64 differ
* in only one character) and the Base64 check is performed
* first. If vflag==B64 and we had a begin line, try to see if
* the data is consistent with XX or UU.
* Check data against all possible encodings
*/
if (vflag == B64ENCODED && result->begin) {
if (UUValidData (line, UU_ENCODED, &bhflag) == UU_ENCODED)
vflag = UU_ENCODED;
else if (UUValidData (line, XX_ENCODED, &bhflag) == XX_ENCODED)
vflag = XX_ENCODED;
isb64[iscnt%10] = (UUValidData (line, B64ENCODED, &bhflag)==B64ENCODED);
isuue[iscnt%10] = (UUValidData (line, UU_ENCODED, &bhflag)==UU_ENCODED);
isxxe[iscnt%10] = (UUValidData (line, XX_ENCODED, &bhflag)==XX_ENCODED);
isbhx[iscnt%10] = (UUValidData (line, BH_ENCODED, &bhflag)==BH_ENCODED);
/*
* If we've got a first valid encoded line, we get suspicious if
* it's shorter than, say, 40 characters.
*/
if (vflag == B64ENCODED &&
(dflag == 0 || encoding != B64ENCODED) &&
strlen (line) < 40 && !result->begin && !uu_tinyb64) {
isb64[iscnt%10] = 0;
vflag = 0;
}
if ((vflag == UU_ENCODED || vflag == XX_ENCODED) &&
(dflag == 0 || encoding != vflag) &&
strlen (line) < 40 && !result->begin) {
isuue[iscnt%10] = isxxe[iscnt%10] = 0;
vflag = 0;
}
iscnt++;
/*
* Ah, so we got an encoded line? How interesting!
*/
if (vflag) {
/*
* For BinHex data, we can use the initial colon ':' as begin
@ -846,6 +906,10 @@ ScanData (FILE *datei, char *fname, int *errcode,
* If (vflag && !bhflag), this is the last line,
*/
if (vflag == BH_ENCODED) {
if (line[0] == ':' && result->end) {
fseek (datei, oldposition, SEEK_SET);
break;
}
if (line[0] == ':')
result->begin = 1;
if (bhflag == 0) {
@ -882,11 +946,43 @@ ScanData (FILE *datei, char *fname, int *errcode,
else if (bhds2[0] <= 0)
bhnf = 1;
}
/*
* everything is fine after we've found three encoded lines
* We accept an encoding if it has been true for four consecutive
* lines. Check the is<enc> arrays to avoid mistaking one encoding
* for the other. Uuencoded data is rather easily mistaken for
* Base 64. If the data matches more than one encoding, we need to
* scan further.
*/
if (dflag>=3 && (vflag==encoding || vflag==result->uudet)) {
result->uudet = vflag;
if (iscnt > 3) {
cbb64 = (isb64[(iscnt-1)%10] && isb64[(iscnt-2)%10] &&
isb64[(iscnt-3)%10] && isb64[(iscnt-4)%10]);
cbuue = (isuue[(iscnt-1)%10] && isuue[(iscnt-2)%10] &&
isuue[(iscnt-3)%10] && isuue[(iscnt-4)%10]);
cbxxe = (isxxe[(iscnt-1)%10] && isxxe[(iscnt-2)%10] &&
isxxe[(iscnt-3)%10] && isxxe[(iscnt-4)%10]);
cbbhx = (isbhx[(iscnt-1)%10] && isbhx[(iscnt-2)%10] &&
isbhx[(iscnt-3)%10] && isbhx[(iscnt-4)%10]);
}
else {
cbb64 = cbuue = cbxxe = cbbhx = 0;
}
if (cbb64 && !cbuue && !cbxxe && !cbbhx) {
result->uudet = B64ENCODED;
}
else if (!cbb64 && cbuue && !cbxxe && !cbbhx) {
result->uudet = UU_ENCODED;
}
else if (!cbb64 && !cbuue && cbxxe && !cbbhx) {
result->uudet = XX_ENCODED;
}
else if (!cbb64 && !cbuue && !cbxxe && cbbhx) {
result->uudet = BH_ENCODED;
}
if (result->uudet) {
encoding = dflag = 0;
/*
@ -978,10 +1074,12 @@ ScanData (FILE *datei, char *fname, int *errcode,
/* pick up ``EOF'' for BinHex files. Slow :-< */
if (line[0] && strchr (line+1, ':') != NULL) {
result->end = 1;
bhflag = 0;
break;
}
}
}
if (ferror (datei) || *errcode == UURET_CANCEL)
break;
@ -998,37 +1096,90 @@ ScanData (FILE *datei, char *fname, int *errcode,
strncmp (line+2, boundary, blen) == 0)) {
break;
}
/*
* Otherwise, we wait until finding something more interesting
* in the outer loop
*/
continue;
}
else if (encoding == XX_ENCODED && vflag == B64ENCODED) {
dflag++;
/*
* Select the encoding with the best "history"
*/
cbb64 = isb64[(iscnt-1)%10];
cbuue = isuue[(iscnt-1)%10];
cbxxe = isxxe[(iscnt-1)%10];
cbbhx = isbhx[(iscnt-1)%10];
dflag = 0;
if (cbb64 || cbuue || cbxxe || cbbhx) {
for (dflag=2; dflag<iscnt && dflag<4; dflag++) {
if ((!cbb64 || !isb64[(iscnt-dflag)%10]) &&
(!cbuue || !isuue[(iscnt-dflag)%10]) &&
(!cbxxe || !isxxe[(iscnt-dflag)%10]) &&
(!cbbhx || !isbhx[(iscnt-dflag)%10])) {
dflag--;
break;
}
cbb64 &= isb64[(iscnt-dflag)%10];
cbuue &= isuue[(iscnt-dflag)%10];
cbxxe &= isxxe[(iscnt-dflag)%10];
cbbhx &= isbhx[(iscnt-dflag)%10];
}
}
else if (result->uudet) {
if (vflag == result->uudet)
dflag++;
else
dflag=0;
/*
* clear-cut cases
*/
if (cbb64 && !cbuue && !cbxxe && !cbbhx) {
encoding = B64ENCODED;
}
else if (!cbb64 && cbuue && !cbxxe && !cbbhx) {
encoding = UU_ENCODED;
}
else if (!cbb64 && !cbuue && cbxxe && !cbbhx) {
encoding = XX_ENCODED;
}
else if (!cbb64 && !cbuue && !cbxxe && cbbhx) {
encoding = BH_ENCODED;
}
else {
encoding = 0;
}
/*
* Check a few common non-clear-cut cases
*/
if (!encoding && cbuue && result->begin) {
encoding = UU_ENCODED;
}
else if (!encoding && cbxxe && result->begin) {
encoding = XX_ENCODED;
}
else if (!encoding && cbb64) {
encoding = B64ENCODED;
}
else if (!encoding && cbuue) {
encoding = UU_ENCODED;
}
else if (!encoding && cbxxe) {
encoding = XX_ENCODED;
}
else if (!encoding && cbbhx) {
encoding = BH_ENCODED;
}
else if (encoding != vflag) {
encoding = vflag;
dflag = 1;
}
else {
encoding = vflag;
dflag++;
}
}
else if (!dontcare) {
encoding = 0;
dflag = 0;
haddh = 0;
}
#if 0
} /* if (!uudet) */
#endif
/*
* End of scanning loop
*/
@ -1054,6 +1205,29 @@ ScanData (FILE *datei, char *fname, int *errcode,
if (result->uudet == B64ENCODED || result->uudet == BH_ENCODED)
result->mode = 6*64+4*8+4;
/*
* When strict MIME adherance is set, throw out suspicious attachments
*/
if (uu_more_mime) {
/*
* In a MIME message, Base64 should be appropriately tagged
*/
if (result->uudet == B64ENCODED) {
result->uudet = 0;
}
/*
* Do not accept incomplete UU or XX encoded messages
*/
if ((result->uudet != 0 && result->uudet != B64ENCODED) &&
(!result->begin || !result->end)) {
result->uudet = 0;
}
}
/*
* In fast mode, this length will yield a false value. We don't care.
* This must be checked for in uunconc(), where we usually stop decoding
@ -1096,8 +1270,8 @@ fileread *
ScanPart (FILE *datei, char *fname, int *errcode)
{
int ecount, hcount, lcount;
int bhflag, begflag, vflag, blen = 0, res;
long preheaders, prevpos = 0, preenc, before;
int bhflag, begflag, vflag, blen=0, res;
long preheaders, prevpos=0, preenc, before;
char *line=uuscan_spline;
fileread *result;
char *ptr1, *ptr2;
@ -1189,6 +1363,35 @@ ScanPart (FILE *datei, char *fname, int *errcode)
}
line[255] = '\0';
/*
* Special handling for AOL folder files, which start off with a boundary.
* We recognize them by a valid boundary line as the first line of a file.
* Note that the rest of the scanning code becomes suspicious if a boun-
* dary does never appear in a file -- this should save us from grave
* false detection errors
*/
if (!feof (datei) && line[0] == '-' && line[1] == '-' && line[2]) {
while (line[strlen(line)-1] == '\012' ||
line[strlen(line)-1] == '\015') {
line[strlen(line)-1] = '\0';
}
sstate.ismime = 1;
sstate.envelope.mimevers = _FP_strdup ("1.0");
sstate.envelope.boundary = _FP_strdup (line+2);
sstate.envelope.ctype = _FP_strdup ("multipart/mixed");
sstate.mimestate = MS_SUBPART;
*errcode = UURET_CONT;
_FP_free (result);
return NULL;
}
/*
* Normal behavior: look for a RFC 822 header
*/
while (!feof (datei) && !IsLineEmpty (line)) {
if (IsKnownHeader (line))
hcount++;
@ -1228,15 +1431,12 @@ ScanPart (FILE *datei, char *fname, int *errcode)
* If we don't have all valid MIME headers yet, but the following
* line is a MIME header, accept it anyway.
*/
#ifndef MORE_MIME
if ((sstate.envelope.mimevers == NULL &&
_FP_strnicmp (line, "Mime-Version:", 13) == 0) ||
(sstate.envelope.ctype == NULL &&
_FP_strnicmp (line, "Content-Type:", 13) == 0) ||
(sstate.envelope.mimevers == NULL &&
sstate.envelope.ctype == NULL &&
sstate.envelope.ctenc == NULL &&
_FP_strnicmp (line, "Content-Transfer-Encoding:", 26) == 0)) {
if (!uu_more_mime &&
sstate.envelope.mimevers == NULL &&
sstate.envelope.ctype == NULL &&
sstate.envelope.ctenc == NULL &&
IsKnownHeader (line)) {
/*
* see above
*/
@ -1256,14 +1456,6 @@ ScanPart (FILE *datei, char *fname, int *errcode)
_FP_free (result);
return NULL;
}
/*
* if we've read too many lines without finding headers, then
* this probably isn't a mail folder after all
*/
lcount++;
if (lcount > WAITHEADER && hcount < hlcount.afternl)
break;
if (_FP_fgets (line, 255, datei) == NULL)
break;
line[255] = '\0';
@ -1282,7 +1474,7 @@ ScanPart (FILE *datei, char *fname, int *errcode)
prevpos = ftell (datei);
}
}
#endif
/*
* A partial multipart message probably has only a Content-Type
* header but nothing else. In this case, at least simulate a
@ -1552,9 +1744,8 @@ ScanPart (FILE *datei, char *fname, int *errcode)
hcount = lcount = 0;
}
#ifndef MORE_MIME
/* check for begin and encoded data only at outermost level */
if (mssdepth == 0) {
if (mssdepth == 0 && !uu_more_mime) {
if (strncmp (line, "begin ", 6) == 0 ||
_FP_strnicmp (line, "<pre>begin ", 11) == 0) {
preenc = prevpos;
@ -1586,13 +1777,13 @@ ScanPart (FILE *datei, char *fname, int *errcode)
ecount = 0;
}
}
#endif
if (!IsLineEmpty (line))
res++;
prevpos = ftell (datei);
}
if (mssdepth > 0 && line[0] == '-' && line[1] == '-' &&
strncmp (line+2,
multistack[mssdepth-1].envelope.boundary, blen) == 0) {
@ -1820,14 +2011,25 @@ ScanPart (FILE *datei, char *fname, int *errcode)
*/
if (_FP_stristr (localenv.ctenc, "base64") != NULL)
result->uudet = B64ENCODED;
else if (_FP_stristr (localenv.ctenc, "x-uue") != NULL)
result->uudet = UU_ENCODED;
else if (_FP_stristr (localenv.ctenc, "quoted-printable") != NULL)
result->uudet = QP_ENCODED;
else if (_FP_stristr (localenv.ctenc, "7bit") != NULL ||
_FP_stristr (localenv.ctenc, "8bit") != NULL)
result->uudet = PT_ENCODED;
else if (_FP_stristr (localenv.ctype, "message") != NULL)
else if (_FP_stristr (localenv.ctype, "multipart") != NULL ||
_FP_stristr (localenv.ctype, "message") != NULL)
result->uudet = PT_ENCODED;
/*
* If we're switched to MIME-only mode, handle as text
*/
if (uu_more_mime >= 2 && !result->uudet) {
result->uudet = PT_ENCODED;
}
if (result->uudet) {
/*
* Oh-kay, go ahead. Just read and wait for the boundary
@ -1940,16 +2142,15 @@ ScanPart (FILE *datei, char *fname, int *errcode)
}
}
/* produce result if uu_handletext is set */
if ((result->uudet == B64ENCODED || uu_handletext) &&
(result->uudet != QP_ENCODED ||
result->uudet != PT_ENCODED || lcount>0)) {
/* or if the file is explicitely named */
if (result->uudet == B64ENCODED || lcount) {
if (localenv.fname) {
_FP_free (result->filename);
if ((result->filename = _FP_strdup (localenv.fname)) == NULL)
*errcode = UURET_NOMEM;
}
else if ((result->uudet==QP_ENCODED||result->uudet==PT_ENCODED) &&
result->filename == NULL) {
result->filename == NULL && uu_handletext) {
sprintf (line, "%04d.txt", ++mimseqno);
if ((result->filename = _FP_strdup (line)) == NULL)
*errcode = UURET_NOMEM;
@ -1984,13 +2185,16 @@ ScanPart (FILE *datei, char *fname, int *errcode)
UUkillheaders (&localenv);
return result;
}
/*
* we're in a subpart, but the local headers don't give us any
* clue about what's to find here. So look for encoded data by
* ourselves.
*/
if ((res = ScanData (datei, fname, errcode,
sstate.envelope.boundary, 1, 0, result)) == -1) {
sstate.envelope.boundary,
1, 0, result)) == -1) {
/* oops, something went wrong */
sstate.isfolder = 0;
sstate.ismime = 0;
@ -2090,17 +2294,29 @@ ScanPart (FILE *datei, char *fname, int *errcode)
sstate.ismime = 0;
}
}
/*
* If this file has been nicely MIME so far, then be very suspicious
* if ScanData reports anything else. So do a double check, and if
* it doesn't hold up, handle as plain text instead.
*/
if (strcmp (localenv.mimevers, "1.0") == 0 &&
_FP_stristr (localenv.ctype, "text") != NULL &&
sstate.ismime && sstate.mimestate == MS_SUBPART &&
!uu_desperate) {
if (result->uudet == UU_ENCODED && !(result->begin || result->end)) {
result->uudet = 0;
}
}
/*
* produce result
*/
if (result->uudet == 0 && uu_handletext) {
if (result->uudet == 0) {
result->uudet = PT_ENCODED; /* plain text */
}
else if (result->uudet == 0) {
UUkillheaders (&localenv);
_FP_free (result);
return NULL;
}
if (localenv.fname) {
_FP_free (result->filename);
@ -2108,7 +2324,7 @@ ScanPart (FILE *datei, char *fname, int *errcode)
*errcode = UURET_NOMEM;
}
else if ((result->uudet==QP_ENCODED || result->uudet==PT_ENCODED) &&
result->filename==NULL) {
result->filename==NULL && uu_handletext) {
sprintf (line, "%04d.txt", ++mimseqno);
if ((result->filename = _FP_strdup (line)) == NULL)
*errcode = UURET_NOMEM;
@ -2234,9 +2450,22 @@ 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)
result->uudet = UU_ENCODED;
else if (_FP_stristr (localenv.ctenc, "7bit") != NULL ||
_FP_stristr (localenv.ctenc, "8bit") != NULL)
result->uudet = PT_ENCODED;
else if (_FP_stristr (localenv.ctype, "multipart") != NULL ||
_FP_stristr (localenv.ctype, "message") != NULL)
result->uudet = PT_ENCODED;
/*
* If we're switched to MIME-only mode, handle as text
*/
if (uu_more_mime >= 2 && !result->uudet) {
result->uudet = PT_ENCODED;
}
}
else {
memset (&localenv, 0, sizeof (headers));
@ -2262,7 +2491,6 @@ ScanPart (FILE *datei, char *fname, int *errcode)
}
else if (result->uudet != 0) {
hcount = lcount = 0;
prevpos = ftell (datei);
if (_FP_stristr (localenv.ctype, "message") != NULL &&
@ -2274,17 +2502,11 @@ ScanPart (FILE *datei, char *fname, int *errcode)
while (!feof (datei)) {
if (_FP_fgets (line, 255, datei) == NULL)
break;
line[255] = '\0';
if (!IsLineEmpty (line)) {
fseek (datei, preheaders, SEEK_SET);
line[255] = '\0';
break;
}
}
if (_FP_fgets (line, 255, datei) == NULL) {
_FP_free (result);
return NULL;
}
line[255] = '\0';
while (!feof (datei) && !IsLineEmpty (line)) {
if (IsKnownHeader (line))
@ -2388,6 +2610,8 @@ 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) |
@ -2435,14 +2659,19 @@ ScanPart (FILE *datei, char *fname, int *errcode)
}
/*
* if this is a MIME body, honor a Content-Type different than
* If this is a MIME body, honor a Content-Type different than
* text/plain or a proper Content-Transfer-Encoding.
* We also go in here if we have an assigned filename - this means
* 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.ctype, "message") != NULL)) {
_FP_stristr (sstate.envelope.ctenc, "x-uue") != NULL ||
_FP_stristr (sstate.envelope.ctype, "message") != NULL ||
sstate.envelope.fname != NULL)) {
if (sstate.envelope.subject)
result->subject = _FP_strdup (sstate.envelope.subject);
@ -2458,16 +2687,32 @@ 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)
result->uudet = UU_ENCODED;
else if (_FP_stristr (sstate.envelope.ctenc, "7bit") != NULL ||
_FP_stristr (sstate.envelope.ctenc, "8bit") != NULL)
result->uudet = PT_ENCODED;
else if (_FP_stristr (sstate.envelope.ctype, "multipart") != NULL ||
_FP_stristr (sstate.envelope.ctype, "message") != NULL)
_FP_stristr (sstate.envelope.ctype, "message") != NULL ||
sstate.envelope.fname != NULL)
result->uudet = PT_ENCODED;
prevpos = ftell (datei);
/*
* If we're switched to MIME-only mode, handle as text
*/
if (uu_more_mime >= 2 && !result->uudet) {
result->uudet = PT_ENCODED;
}
result->startpos = prevpos = ftell (datei);
/*
* If this is Quoted-Printable or Plain Text, just try looking
* for the next message header. If uu_fast_scanning, we know
* there won't be more headers.
* If it is a "trivial" (non-embedded) message/rfc822, skip over
* the message header and then start looking for the next header.
*/
if (result->uudet != 0 && uu_fast_scanning) {
/* do nothing */
@ -2475,8 +2720,43 @@ ScanPart (FILE *datei, char *fname, int *errcode)
}
else if (result->uudet != 0) {
hcount = lcount = 0;
prevpos = ftell (datei);
if (_FP_stristr (sstate.envelope.ctype, "message") != NULL &&
_FP_stristr (sstate.envelope.ctype, "rfc822") != NULL) {
/*
* skip over empty lines and local header
*/
preheaders = ftell (datei);
while (!feof (datei)) {
if (_FP_fgets (line, 255, datei) == NULL)
break;
line[255] = '\0';
if (!IsLineEmpty (line)) {
break;
}
}
while (!feof (datei) && !IsLineEmpty (line)) {
if (IsKnownHeader (line))
hcount++;
lcount++;
if (lcount > WAITHEADER && hcount < hlcount.afternl)
break;
if (_FP_fgets (line, 255, datei) == NULL)
break;
line[255] = '\0';
}
if (hcount < hlcount.afternl)
fseek (datei, preheaders, SEEK_SET);
hcount = lcount = 0;
}
/*
* look for next header
*/
while (!feof (datei)) {
if (_FP_fgets (line, 255, datei) == NULL)
break;
@ -2592,7 +2872,6 @@ ScanPart (FILE *datei, char *fname, int *errcode)
return result;
}
#ifndef MORE_MIME
/*
* Some files have reduced headers, and what should be a multipart
* message is missing the proper Content-Type. If the first thing
@ -2604,8 +2883,10 @@ ScanPart (FILE *datei, char *fname, int *errcode)
* we know that sstate.envelope.boundary is NULL, or we wouldn't
* be here!
*/
if (sstate.envelope.ctype == NULL ||
_FP_stristr (sstate.envelope.ctype, "multipart") != NULL) {
if ((sstate.envelope.ctype == NULL ||
_FP_stristr (sstate.envelope.ctype, "multipart") != NULL) &&
!uu_more_mime) {
prevpos = ftell (datei);
while (!feof (datei)) {
if (_FP_fgets (line, 255, datei) == NULL) {
@ -2650,7 +2931,6 @@ ScanPart (FILE *datei, char *fname, int *errcode)
}
fseek (datei, prevpos, SEEK_SET);
}
#endif
/*
* Hmm, we're not in a ''special'' state, so it's more or less

View File

@ -1,7 +1,7 @@
/*
* This file is part of uudeview, the simple and friendly multi-part multi-
* file uudecoder program (c) 1994 by Frank Pilhofer. The author may be
* contacted by his email address, fp@informatik.uni-frankfurt.de
* file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may
* be contacted at fp@fpx.de
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -1,4 +1,4 @@
/* extracted from Id: uustring.c,v 1.1 2000/01/27 18:44:38 asa Exp */
/* extracted from Id: uustring.c,v 1.6 2001/06/06 18:21:47 fp Exp */
#define S_NOT_OPEN_SOURCE 1
#define S_NOT_OPEN_TARGET 2
#define S_NOT_OPEN_FILE 3

View File

@ -1,7 +1,7 @@
/*
* This file is part of uudeview, the simple and friendly multi-part multi-
* file uudecoder program (c) 1994 by Frank Pilhofer. The author may be
* contacted by his email address, fp@informatik.uni-frankfurt.de
* file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may
* be contacted at fp@fpx.de
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -477,9 +477,3 @@ UUSmerge (int pass)
return flag;
}
/*****************************************************************************
+ Frank Pilhofer fp@informatik.uni-frankfurt.de +
+---------------------------------------------------------------------------+
| Department of Computer Sciences * University of Frankfurt / Main, Germany |
*****************************************************************************/