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/ 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 - Fixed improper charset conversion when replying on message without
charset between areas with different Xlatimport. charset between areas with different Xlatimport.

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of uudeview, the simple and friendly multi-part multi- * 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 * file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may
* contacted by his email address, fp@informatik.uni-frankfurt.de * be contacted at fp@fpx.de
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -14,7 +14,6 @@
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -847,7 +846,7 @@ UUPreProcessPart (fileread *data, int *ret)
} }
lastvalid = 0; lastvalid = 0;
} }
else if (lastvalid && data->uudet == lastenc) { else if (lastvalid && data->uudet == lastenc && result->partno <= 0) {
result->subfname = _FP_strdup (uucheck_lastname); result->subfname = _FP_strdup (uucheck_lastname);
result->partno = ++lastpart; result->partno = ++lastpart;
@ -857,6 +856,9 @@ UUPreProcessPart (fileread *data, int *ret)
if (data->end || (data->partno && data->partno == data->maxpno)) if (data->end || (data->partno && data->partno == data->maxpno))
lastvalid = 0; lastvalid = 0;
} }
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 * it's got no info, it's got no begin, and we don't know anything
@ -1460,9 +1462,3 @@ UUCheckGlobalList (void)
return UUGlobalFileList; 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- * 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 * file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may
* contacted by his email address, fp@informatik.uni-frankfurt.de * be contacted at fp@fpx.de
* *
* This program is free software; you can redistribute it and/or modify * 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 * 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_PREAMB (17) /* handle Mime preambles/epilogues */
#define UUOPT_TINYB64 (18) /* detect short B64 outside of Mime */ #define UUOPT_TINYB64 (18) /* detect short B64 outside of Mime */
#define UUOPT_ENCEXT (19) /* extension for single-part encoded files */ #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 * Code for the "action" in the progress structure
@ -239,6 +241,19 @@ int UUEXPORT UUE_PrepPartial _ANSI_ARGS_((FILE *, FILE *,
char *, int, char *, int,
int, long, long, char *, int, long, long, char *,
char *, char *, int)); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of uudeview, the simple and friendly multi-part multi- * 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 * file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may
* contacted by his email address, fp@informatik.uni-frankfurt.de * be contacted at fp@fpx.de
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -98,9 +98,9 @@ char * uuencode_id = "$Id$";
*/ */
#ifdef EOLSTRING #ifdef EOLSTRING
static unsigned char *eolstring = (unsigned char *) EOLSTRING; static char *eolstring = (char *) EOLSTRING;
#else #else
static unsigned char *eolstring = (unsigned char *) "\012"; static char *eolstring = (char *) "\012";
#endif #endif
/* /*
@ -114,6 +114,8 @@ static unsigned char *eolstring = (unsigned char *) "\012";
#define CTE_TYPE(y) (((y)==B64ENCODED) ? "Base64" : \ #define CTE_TYPE(y) (((y)==B64ENCODED) ? "Base64" : \
((y)==UU_ENCODED) ? CTE_UUENC : \ ((y)==UU_ENCODED) ? CTE_UUENC : \
((y)==XX_ENCODED) ? CTE_XXENC : \ ((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 : "x-oops")
/* /*
@ -165,6 +167,11 @@ unsigned char BHEncodeTable[64] = {
'i', 'j', 'k', 'l', 'm', 'p', 'q', 'r' '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 { typedef struct {
char *extension; char *extension;
char *mimetype; char *mimetype;
@ -191,7 +198,7 @@ static mimemap mimetable[] = {
{ "mpeg", "video/mpeg" }, /* Motion Picture Expert Group */ { "mpeg", "video/mpeg" }, /* Motion Picture Expert Group */
{ "mpg", "video/mpeg" }, { "mpg", "video/mpeg" },
{ "mp2", "video/mpeg" }, /* dito, MPEG-2 encoded files */ { "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 */ { "ps", "application/postscript" }, /* Postscript Language */
{ "zip", "application/zip" }, /* ZIP archive */ { "zip", "application/zip" }, /* ZIP archive */
{ "doc", "application/msword"},/* assume Microsoft Word */ { "doc", "application/msword"},/* assume Microsoft Word */
@ -243,12 +250,161 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile)
size_t llen; size_t llen;
if (outfile==NULL || infile==NULL || 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, UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
uustring (S_PARM_CHECK), "UUEncodeStream()"); uustring (S_PARM_CHECK), "UUEncodeStream()");
return UURET_ILLVAL; 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 * select charset
@ -269,6 +425,7 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile)
else if (ferror (infile)) else if (ferror (infile))
return UURET_IOERR; return UURET_IOERR;
} }
optr = otemp; optr = otemp;
llen = 0; llen = 0;
@ -285,21 +442,29 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile)
/* /*
* for UU and XX, encode the number of bytes as first character * for UU and XX, encode the number of bytes as first character
*/ */
if (encoding == UU_ENCODED || encoding == XX_ENCODED) { if (encoding == UU_ENCODED || encoding == XX_ENCODED) {
*optr++ = table[count]; *optr++ = table[count];
llen++; llen++;
} }
/*
* Main encoding
*/
if (encoding == UU_ENCODED || encoding == XX_ENCODED ||
encoding == B64ENCODED) {
for (index=0; index<=count-3; index+=3, llen+=4) { for (index=0; index<=count-3; index+=3, llen+=4) {
*optr++ = table[itemp[index] >> 2]; *optr++ = table[itemp[index] >> 2];
*optr++ = table[((itemp[index ] & 0x03) << 4) | (itemp[index+1] >> 4)]; *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+1] & 0x0f) << 2)|(itemp[index+2] >> 6)];
*optr++ = table[ itemp[index+2] & 0x3f]; *optr++ = table[ itemp[index+2] & 0x3f];
} }
/* /*
* Special handling for incomplete lines * Special handling for incomplete lines
*/ */
if (index != count) { if (index != count) {
if (encoding == B64ENCODED) { if (encoding == B64ENCODED) {
if (count - index == 2) { if (count - index == 2) {
@ -334,16 +499,19 @@ UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile)
llen += 4; llen += 4;
} }
} }
}
/* /*
* end of line * end of line
*/ */
tptr = eolstring;
tptr = (unsigned char *) eolstring;
while (*tptr) while (*tptr)
*optr++ = *tptr++; *optr++ = *tptr++;
*optr++ = '\0'; *optr++ = '\0';
llen += strlen ((char *) eolstring); llen += strlen (eolstring);
if (fwrite (otemp, 1, llen, outfile) != llen) if (fwrite (otemp, 1, llen, outfile) != llen)
return UURET_IOERR; return UURET_IOERR;
@ -370,7 +538,8 @@ UUEncodeMulti (FILE *outfile, FILE *infile, char *infname, int encoding,
if (outfile==NULL || if (outfile==NULL ||
(infile == NULL && infname==NULL) || (infile == NULL && infname==NULL) ||
(outfname==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, UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
uustring (S_PARM_CHECK), "UUEncodeMulti()"); uustring (S_PARM_CHECK), "UUEncodeMulti()");
return UURET_ILLVAL; return UURET_ILLVAL;
@ -430,6 +599,11 @@ UUEncodeMulti (FILE *outfile, FILE *infile, char *infname, int encoding,
mimetype = miter->mimetype; mimetype = miter->mimetype;
} }
} }
if (mimetype == NULL && (encoding == PT_ENCODED || encoding == QP_ENCODED)) {
mimetype = "text/plain";
}
/* /*
* print sub-header * print sub-header
*/ */
@ -497,7 +671,8 @@ UUEncodePartial (FILE *outfile, FILE *infile,
if ((outfname==NULL&&infname==NULL) || partno<=0 || if ((outfname==NULL&&infname==NULL) || partno<=0 ||
(infile == NULL&&infname==NULL) || outfile==NULL || (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, UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
uustring (S_PARM_CHECK), "UUEncodePartial()"); uustring (S_PARM_CHECK), "UUEncodePartial()");
return UURET_ILLVAL; return UURET_ILLVAL;
@ -574,6 +749,11 @@ UUEncodePartial (FILE *outfile, FILE *infile,
mimetype = miter->mimetype; mimetype = miter->mimetype;
} }
} }
if (mimetype == NULL && (encoding==PT_ENCODED || encoding==QP_ENCODED)) {
mimetype = "text/plain";
}
/* /*
* print sub-header * print sub-header
*/ */
@ -639,10 +819,14 @@ UUEncodePartial (FILE *outfile, FILE *infile,
eolstring); eolstring);
fprintf (outfile, "end%s", eolstring); fprintf (outfile, "end%s", eolstring);
} }
/* /*
* empty line at end does no harm * empty line at end does no harm
*/ */
if (encoding != PT_ENCODED && encoding != QP_ENCODED) {
fprintf (outfile, "%s", eolstring); fprintf (outfile, "%s", eolstring);
}
if (infile==NULL) { if (infile==NULL) {
if (res != UURET_OK) { if (res != UURET_OK) {
@ -682,7 +866,8 @@ UUEncodeToStream (FILE *outfile, FILE *infile,
if (outfile==NULL || if (outfile==NULL ||
(infile == NULL&&infname==NULL) || (infile == NULL&&infname==NULL) ||
(outfname==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, UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
uustring (S_PARM_CHECK), "UUEncodeToStream()"); uustring (S_PARM_CHECK), "UUEncodeToStream()");
return UURET_ILLVAL; return UURET_ILLVAL;
@ -778,7 +963,8 @@ UUEncodeToFile (FILE *infile, char *infname, int encoding,
if ((diskname==NULL&&infname==NULL) || if ((diskname==NULL&&infname==NULL) ||
(outfname==NULL&&infname==NULL) || (infile==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, UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
uustring (S_PARM_CHECK), "UUEncodeToFile()"); uustring (S_PARM_CHECK), "UUEncodeToFile()");
return UURET_ILLVAL; return UURET_ILLVAL;
@ -1012,6 +1198,22 @@ UUE_PrepSingle (FILE *outfile, FILE *infile,
char *outfname, int filemode, char *outfname, int filemode,
char *destination, char *from, char *destination, char *from,
char *subject, int isemail) 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; mimemap *miter=mimetable;
char *subline, *oname; char *subline, *oname;
@ -1019,7 +1221,8 @@ UUE_PrepSingle (FILE *outfile, FILE *infile,
int res, len; int res, len;
if ((outfname==NULL&&infname==NULL) || (infile==NULL&&infname==NULL) || 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, UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
uustring (S_PARM_CHECK), "UUE_PrepSingle()"); uustring (S_PARM_CHECK), "UUE_PrepSingle()");
return UURET_ILLVAL; return UURET_ILLVAL;
@ -1036,6 +1239,10 @@ UUE_PrepSingle (FILE *outfile, FILE *infile,
else else
mimetype = NULL; mimetype = NULL;
if (mimetype == NULL && (encoding == PT_ENCODED || encoding == QP_ENCODED)) {
mimetype = "text/plain";
}
if ((subline = (char *) malloc (len)) == NULL) { if ((subline = (char *) malloc (len)) == NULL) {
UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
uustring (S_OUT_OF_MEMORY), len); uustring (S_OUT_OF_MEMORY), len);
@ -1047,8 +1254,6 @@ UUE_PrepSingle (FILE *outfile, FILE *infile,
else else
sprintf (subline, "[ %s ] (001/001)", oname); sprintf (subline, "[ %s ] (001/001)", oname);
fprintf (outfile, "Subject: %s%s", subline, eolstring);
if (from) { if (from) {
fprintf (outfile, "From: %s%s", from, eolstring); fprintf (outfile, "From: %s%s", from, eolstring);
} }
@ -1057,6 +1262,13 @@ UUE_PrepSingle (FILE *outfile, FILE *infile,
(isemail)?"To":"Newsgroups", (isemail)?"To":"Newsgroups",
destination, eolstring); 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, "MIME-Version: 1.0%s", eolstring);
fprintf (outfile, "Content-Type: %s; name=\"%s\"%s", fprintf (outfile, "Content-Type: %s; name=\"%s\"%s",
(mimetype)?mimetype:"Application/Octet-Stream", (mimetype)?mimetype:"Application/Octet-Stream",
@ -1080,6 +1292,24 @@ UUE_PrepPartial (FILE *outfile, FILE *infile,
int partno, long linperfile, long filesize, int partno, long linperfile, long filesize,
char *destination, char *from, char *subject, char *destination, char *from, char *subject,
int isemail) 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 int numparts, themode;
static char mimeid[64]; static char mimeid[64];
@ -1090,7 +1320,8 @@ UUE_PrepPartial (FILE *outfile, FILE *infile,
int res, len; int res, len;
if ((outfname==NULL&&infname==NULL) || (infile==NULL&&infname==NULL) || 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, UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
uustring (S_PARM_CHECK), "UUE_PrepPartial()"); uustring (S_PARM_CHECK), "UUE_PrepPartial()");
return UURET_ILLVAL; return UURET_ILLVAL;
@ -1163,9 +1394,9 @@ UUE_PrepPartial (FILE *outfile, FILE *infile,
if (numparts == 1) { if (numparts == 1) {
if (infile==NULL) fclose (theifile); if (infile==NULL) fclose (theifile);
return UUE_PrepSingle (outfile, infile, infname, encoding, return UUE_PrepSingleExt (outfile, infile, infname, encoding,
outfname, filemode, destination, outfname, filemode, destination,
from, subject, isemail); from, subject, replyto, isemail);
} }
/* /*
@ -1190,16 +1421,22 @@ UUE_PrepPartial (FILE *outfile, FILE *infile,
sprintf (subline, "[ %s ] (%03d/%03d)", sprintf (subline, "[ %s ] (%03d/%03d)",
oname, partno, numparts); oname, partno, numparts);
fprintf (outfile, "Subject: %s%s", subline, eolstring);
if (from) { if (from) {
fprintf (outfile, "From: %s%s", from, eolstring); fprintf (outfile, "From: %s%s", from, eolstring);
} }
if (destination) { if (destination) {
fprintf (outfile, "%s: %s%s", fprintf (outfile, "%s: %s%s",
(isemail)?"To":"Newsgroups", (isemail)?"To":"Newsgroups",
destination, eolstring); 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, "MIME-Version: 1.0%s", eolstring);
fprintf (outfile, "Content-Type: Message/Partial; number=%d; total=%d;%s", fprintf (outfile, "Content-Type: Message/Partial; number=%d; total=%d;%s",
partno, numparts, eolstring); partno, numparts, eolstring);

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of uudeview, the simple and friendly multi-part multi- * 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 * file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may
* contacted by his email address, fp@informatik.uni-frankfurt.de * be contacted at fp@fpx.de
* *
* This program is free software; you can redistribute it and/or modify * 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 * 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_usepreamble;
extern int uu_handletext; extern int uu_handletext;
extern int uu_tinyb64; extern int uu_tinyb64;
extern int uu_remove_input;
extern int uu_more_mime;
extern char *uusavepath; extern char *uusavepath;
extern char *uuencodeext; extern char *uuencodeext;

View File

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

View File

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

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of uudeview, the simple and friendly multi-part multi- * 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 * file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may
* contacted by his email address, fp@informatik.uni-frankfurt.de * be contacted at fp@fpx.de
* *
* This program is free software; you can redistribute it and/or modify * 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 * 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_sdbhds2;
char *uuscan_spline; 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 * Macro: print cancellation message in UUScanPart
*/ */
@ -338,32 +332,35 @@ ParseHeader (headers *theheaders, char *line)
if (line == NULL) if (line == NULL)
return theheaders; return theheaders;
value = NULL; delimit = 0;
if (_FP_strnicmp (line, "From:", 5) == 0) { if (_FP_strnicmp (line, "From:", 5) == 0) {
if (theheaders->from) return theheaders; if (theheaders->from) return theheaders;
variable = &theheaders->from; variable = &theheaders->from;
value = line+5; value = line+5;
delimit = 0;
} }
else if (_FP_strnicmp (line, "Subject:", 8) == 0) { else if (_FP_strnicmp (line, "Subject:", 8) == 0) {
if (theheaders->subject) return theheaders; if (theheaders->subject) return theheaders;
variable = &theheaders->subject; variable = &theheaders->subject;
value = line+8; value = line+8;
delimit = 0;
} }
else if (_FP_strnicmp (line, "To:", 3) == 0) { else if (_FP_strnicmp (line, "To:", 3) == 0) {
if (theheaders->rcpt) return theheaders; if (theheaders->rcpt) return theheaders;
variable = &theheaders->rcpt; variable = &theheaders->rcpt;
value = line+3; value = line+3;
delimit = 0;
} }
else if (_FP_strnicmp (line, "Date:", 5) == 0) { else if (_FP_strnicmp (line, "Date:", 5) == 0) {
if (theheaders->date) return theheaders; if (theheaders->date) return theheaders;
variable = &theheaders->date; variable = &theheaders->date;
value = line+5; value = line+5;
delimit = 0;
} }
else if (_FP_strnicmp (line, "Mime-Version:", 13) == 0) { else if (_FP_strnicmp (line, "Mime-Version:", 13) == 0) {
if (theheaders->mimevers) return theheaders; if (theheaders->mimevers) return theheaders;
variable = &theheaders->mimevers; variable = &theheaders->mimevers;
value = line+13; value = line+13;
delimit = 0;
} }
else if (_FP_strnicmp (line, "Content-Type:", 13) == 0) { else if (_FP_strnicmp (line, "Content-Type:", 13) == 0) {
if (theheaders->ctype) return theheaders; if (theheaders->ctype) return theheaders;
@ -420,12 +417,16 @@ ParseHeader (headers *theheaders, char *line)
} }
} }
variable = NULL; variable = NULL;
value = NULL;
delimit = 0;
} }
else { else {
/* /*
* nothing interesting * nothing interesting
*/ */
variable = NULL; 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; char *line=uuscan_sdline, *bhds1=uuscan_sdbhds1, *bhds2=uuscan_sdbhds2;
static char *ptr, *p2, *p3=NULL, *bhdsp, bhl; 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 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 encoding=0, dflag=0, ctline=42;
int dontcare=0, hadnl=0; int dontcare=0, hadnl=0;
long preheaders = 0, oldposition; long preheaders=0, oldposition;
size_t dcc, bhopc; size_t dcc, bhopc;
*errcode = UURET_OK; *errcode = UURET_OK;
@ -536,7 +539,14 @@ ScanData (FILE *datei, char *fname, int *errcode,
result->startpos = ftell (datei); result->startpos = ftell (datei);
hcount = lcount = 0; 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)) { while (!feof (datei)) {
oldposition = ftell (datei); oldposition = ftell (datei);
@ -547,15 +557,10 @@ ScanData (FILE *datei, char *fname, int *errcode,
line[255] = '\0'; /* For Safety of string functions */ line[255] = '\0'; /* For Safety of string functions */
if (IsLineEmpty (line)) { /* line empty? */
hcount = 0;
hadnl = 1;
continue; /* then ignore */
}
/* /*
* Make Busy Polls * Make Busy Polls
*/ */
if (UUBUSYPOLL(ftell(datei),progress.fsize)) { if (UUBUSYPOLL(ftell(datei),progress.fsize)) {
UUMessage (uuscan_id, __LINE__, UUMSG_NOTE, UUMessage (uuscan_id, __LINE__, UUMSG_NOTE,
uustring (S_SCAN_CANCEL)); uustring (S_SCAN_CANCEL));
@ -563,6 +568,12 @@ ScanData (FILE *datei, char *fname, int *errcode,
break; break;
} }
if (IsLineEmpty (line)) { /* line empty? */
hcount = 0;
hadnl = 1;
continue; /* then ignore */
}
if (checkheaders) { if (checkheaders) {
if (IsKnownHeader (line)) { if (IsKnownHeader (line)) {
(void) ScanHeaderLine (datei, line); (void) ScanHeaderLine (datei, line);
@ -606,6 +617,7 @@ ScanData (FILE *datei, char *fname, int *errcode,
else { else {
dontcare=0; dontcare=0;
} }
if (boundary != NULL && if (boundary != NULL &&
line[0] == '-' && line[1] == '-' && line[0] == '-' && line[1] == '-' &&
strncmp (line+2, boundary, blen) == 0) { strncmp (line+2, boundary, blen) == 0) {
@ -629,8 +641,9 @@ ScanData (FILE *datei, char *fname, int *errcode,
if (strncmp (line, "begin ", 6) == 0 || if (strncmp (line, "begin ", 6) == 0 ||
_FP_strnicmp (line, "<pre>begin ", 11) == 0) { _FP_strnicmp (line, "<pre>begin ", 11) == 0) {
if (result->begin || result->end || if ((result->begin || result->end ||
result->uudet == B64ENCODED || result->uudet == BH_ENCODED) { result->uudet == B64ENCODED ||
result->uudet == BH_ENCODED) && !uu_more_mime) {
fseek (datei, oldposition, SEEK_SET); fseek (datei, oldposition, SEEK_SET);
break; break;
} }
@ -673,15 +686,20 @@ ScanData (FILE *datei, char *fname, int *errcode,
hadnl = 0; 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) { if (result->uudet) {
fseek (datei, oldposition, SEEK_SET); fseek (datei, oldposition, SEEK_SET);
break; break;
} }
result->partno = atoi (line + 8); 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) { if ((ptr = _FP_stristr (line, "of file ")) != NULL) {
ptr += 8; ptr += 8;
while (isspace (*ptr)) ptr++; 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 * Some reduced MIME handling. Only use if boundary == NULL. Also
* accept the "X-Orcl-Content-Type" used by some braindead program. * 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 || if (_FP_strnicmp (line, "Content-Type", 12) == 0 ||
_FP_strnicmp (line, "X-Orcl-Content-Type", 19) == 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. * Handling for very short Base64 files.
*/ */
if (uu_tinyb64) { if (uu_tinyb64 && !ismime && !uu_more_mime) {
if (line[0] == '-' && line[1] == '-') { if (line[0] == '-' && line[1] == '-') {
if (dflag && (encoding==B64ENCODED || result->uudet==B64ENCODED)) { if (dflag && (encoding==B64ENCODED || result->uudet==B64ENCODED)) {
if (encoding==B64ENCODED && result->uudet==0 && (haddh||hadct)) { if (encoding==B64ENCODED && result->uudet==0 && (haddh||hadct)) {
@ -811,34 +829,76 @@ ScanData (FILE *datei, char *fname, int *errcode,
} }
} /* end of reduced MIME handling */ } /* 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 we haven't yet found anything encoded, try to find something
*/ */
#if 0
if (!(result->uudet)) { if (!(result->uudet)) {
#endif
/* /*
* Netscape-Repair code is the same as in uunconc.c * 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); vflag = UURepairData (datei, line, 0, &bhflag);
/* /*
* In a few cases, we might mistake uu or xx-encoded data for * Check data against all possible encodings
* 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.
*/ */
if (vflag == B64ENCODED && result->begin) {
if (UUValidData (line, UU_ENCODED, &bhflag) == UU_ENCODED) isb64[iscnt%10] = (UUValidData (line, B64ENCODED, &bhflag)==B64ENCODED);
vflag = UU_ENCODED; isuue[iscnt%10] = (UUValidData (line, UU_ENCODED, &bhflag)==UU_ENCODED);
else if (UUValidData (line, XX_ENCODED, &bhflag) == XX_ENCODED) isxxe[iscnt%10] = (UUValidData (line, XX_ENCODED, &bhflag)==XX_ENCODED);
vflag = 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) { if (vflag) {
/* /*
* For BinHex data, we can use the initial colon ':' as begin * 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 && !bhflag), this is the last line,
*/ */
if (vflag == BH_ENCODED) { if (vflag == BH_ENCODED) {
if (line[0] == ':' && result->end) {
fseek (datei, oldposition, SEEK_SET);
break;
}
if (line[0] == ':') if (line[0] == ':')
result->begin = 1; result->begin = 1;
if (bhflag == 0) { if (bhflag == 0) {
@ -882,11 +946,43 @@ ScanData (FILE *datei, char *fname, int *errcode,
else if (bhds2[0] <= 0) else if (bhds2[0] <= 0)
bhnf = 1; 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; encoding = dflag = 0;
/* /*
@ -978,10 +1074,12 @@ ScanData (FILE *datei, char *fname, int *errcode,
/* pick up ``EOF'' for BinHex files. Slow :-< */ /* pick up ``EOF'' for BinHex files. Slow :-< */
if (line[0] && strchr (line+1, ':') != NULL) { if (line[0] && strchr (line+1, ':') != NULL) {
result->end = 1; result->end = 1;
bhflag = 0;
break; break;
} }
} }
} }
if (ferror (datei) || *errcode == UURET_CANCEL) if (ferror (datei) || *errcode == UURET_CANCEL)
break; break;
@ -998,27 +1096,82 @@ ScanData (FILE *datei, char *fname, int *errcode,
strncmp (line+2, boundary, blen) == 0)) { strncmp (line+2, boundary, blen) == 0)) {
break; break;
} }
/* /*
* Otherwise, we wait until finding something more interesting * Otherwise, we wait until finding something more interesting
* in the outer loop * 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;
} }
else if (result->uudet) { cbb64 &= isb64[(iscnt-dflag)%10];
if (vflag == result->uudet) cbuue &= isuue[(iscnt-dflag)%10];
dflag++; cbxxe &= isxxe[(iscnt-dflag)%10];
else cbbhx &= isbhx[(iscnt-dflag)%10];
dflag=0;
} }
else if (encoding != vflag) { }
encoding = vflag;
dflag = 1; /*
* 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 { else {
encoding = vflag; encoding = 0;
dflag++; }
/*
* 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 (!dontcare) { else if (!dontcare) {
@ -1026,9 +1179,7 @@ ScanData (FILE *datei, char *fname, int *errcode,
dflag = 0; dflag = 0;
haddh = 0; haddh = 0;
} }
#if 0
} /* if (!uudet) */ } /* if (!uudet) */
#endif
/* /*
* End of scanning loop * End of scanning loop
*/ */
@ -1054,6 +1205,29 @@ ScanData (FILE *datei, char *fname, int *errcode,
if (result->uudet == B64ENCODED || result->uudet == BH_ENCODED) if (result->uudet == B64ENCODED || result->uudet == BH_ENCODED)
result->mode = 6*64+4*8+4; 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. * 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 * This must be checked for in uunconc(), where we usually stop decoding
@ -1096,8 +1270,8 @@ fileread *
ScanPart (FILE *datei, char *fname, int *errcode) ScanPart (FILE *datei, char *fname, int *errcode)
{ {
int ecount, hcount, lcount; int ecount, hcount, lcount;
int bhflag, begflag, vflag, blen = 0, res; int bhflag, begflag, vflag, blen=0, res;
long preheaders, prevpos = 0, preenc, before; long preheaders, prevpos=0, preenc, before;
char *line=uuscan_spline; char *line=uuscan_spline;
fileread *result; fileread *result;
char *ptr1, *ptr2; char *ptr1, *ptr2;
@ -1189,6 +1363,35 @@ ScanPart (FILE *datei, char *fname, int *errcode)
} }
line[255] = '\0'; 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)) { while (!feof (datei) && !IsLineEmpty (line)) {
if (IsKnownHeader (line)) if (IsKnownHeader (line))
hcount++; 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 * If we don't have all valid MIME headers yet, but the following
* line is a MIME header, accept it anyway. * line is a MIME header, accept it anyway.
*/ */
#ifndef MORE_MIME
if ((sstate.envelope.mimevers == NULL && if (!uu_more_mime &&
_FP_strnicmp (line, "Mime-Version:", 13) == 0) || sstate.envelope.mimevers == NULL &&
(sstate.envelope.ctype == NULL &&
_FP_strnicmp (line, "Content-Type:", 13) == 0) ||
(sstate.envelope.mimevers == NULL &&
sstate.envelope.ctype == NULL && sstate.envelope.ctype == NULL &&
sstate.envelope.ctenc == NULL && sstate.envelope.ctenc == NULL &&
_FP_strnicmp (line, "Content-Transfer-Encoding:", 26) == 0)) { IsKnownHeader (line)) {
/* /*
* see above * see above
*/ */
@ -1256,14 +1456,6 @@ ScanPart (FILE *datei, char *fname, int *errcode)
_FP_free (result); _FP_free (result);
return NULL; 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) if (_FP_fgets (line, 255, datei) == NULL)
break; break;
line[255] = '\0'; line[255] = '\0';
@ -1282,7 +1474,7 @@ ScanPart (FILE *datei, char *fname, int *errcode)
prevpos = ftell (datei); prevpos = ftell (datei);
} }
} }
#endif
/* /*
* A partial multipart message probably has only a Content-Type * A partial multipart message probably has only a Content-Type
* header but nothing else. In this case, at least simulate a * 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; hcount = lcount = 0;
} }
#ifndef MORE_MIME
/* check for begin and encoded data only at outermost level */ /* 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 || if (strncmp (line, "begin ", 6) == 0 ||
_FP_strnicmp (line, "<pre>begin ", 11) == 0) { _FP_strnicmp (line, "<pre>begin ", 11) == 0) {
preenc = prevpos; preenc = prevpos;
@ -1586,13 +1777,13 @@ ScanPart (FILE *datei, char *fname, int *errcode)
ecount = 0; ecount = 0;
} }
} }
#endif
if (!IsLineEmpty (line)) if (!IsLineEmpty (line))
res++; res++;
prevpos = ftell (datei); prevpos = ftell (datei);
} }
if (mssdepth > 0 && line[0] == '-' && line[1] == '-' && if (mssdepth > 0 && line[0] == '-' && line[1] == '-' &&
strncmp (line+2, strncmp (line+2,
multistack[mssdepth-1].envelope.boundary, blen) == 0) { 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) if (_FP_stristr (localenv.ctenc, "base64") != NULL)
result->uudet = B64ENCODED; 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) else if (_FP_stristr (localenv.ctenc, "quoted-printable") != NULL)
result->uudet = QP_ENCODED; result->uudet = QP_ENCODED;
else if (_FP_stristr (localenv.ctenc, "7bit") != NULL || else if (_FP_stristr (localenv.ctenc, "7bit") != NULL ||
_FP_stristr (localenv.ctenc, "8bit") != NULL) _FP_stristr (localenv.ctenc, "8bit") != NULL)
result->uudet = PT_ENCODED; 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; 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) { if (result->uudet) {
/* /*
* Oh-kay, go ahead. Just read and wait for the boundary * 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 */ /* produce result if uu_handletext is set */
if ((result->uudet == B64ENCODED || uu_handletext) && /* or if the file is explicitely named */
(result->uudet != QP_ENCODED || if (result->uudet == B64ENCODED || lcount) {
result->uudet != PT_ENCODED || lcount>0)) {
if (localenv.fname) { if (localenv.fname) {
_FP_free (result->filename); _FP_free (result->filename);
if ((result->filename = _FP_strdup (localenv.fname)) == NULL) if ((result->filename = _FP_strdup (localenv.fname)) == NULL)
*errcode = UURET_NOMEM; *errcode = UURET_NOMEM;
} }
else if ((result->uudet==QP_ENCODED||result->uudet==PT_ENCODED) && else if ((result->uudet==QP_ENCODED||result->uudet==PT_ENCODED) &&
result->filename == NULL) { result->filename == NULL && uu_handletext) {
sprintf (line, "%04d.txt", ++mimseqno); sprintf (line, "%04d.txt", ++mimseqno);
if ((result->filename = _FP_strdup (line)) == NULL) if ((result->filename = _FP_strdup (line)) == NULL)
*errcode = UURET_NOMEM; *errcode = UURET_NOMEM;
@ -1984,13 +2185,16 @@ ScanPart (FILE *datei, char *fname, int *errcode)
UUkillheaders (&localenv); UUkillheaders (&localenv);
return result; return result;
} }
/* /*
* we're in a subpart, but the local headers don't give us any * 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 * clue about what's to find here. So look for encoded data by
* ourselves. * ourselves.
*/ */
if ((res = ScanData (datei, fname, errcode, if ((res = ScanData (datei, fname, errcode,
sstate.envelope.boundary, 1, 0, result)) == -1) { sstate.envelope.boundary,
1, 0, result)) == -1) {
/* oops, something went wrong */ /* oops, something went wrong */
sstate.isfolder = 0; sstate.isfolder = 0;
sstate.ismime = 0; sstate.ismime = 0;
@ -2090,17 +2294,29 @@ ScanPart (FILE *datei, char *fname, int *errcode)
sstate.ismime = 0; 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 * produce result
*/ */
if (result->uudet == 0 && uu_handletext) {
if (result->uudet == 0) {
result->uudet = PT_ENCODED; /* plain text */ result->uudet = PT_ENCODED; /* plain text */
} }
else if (result->uudet == 0) {
UUkillheaders (&localenv);
_FP_free (result);
return NULL;
}
if (localenv.fname) { if (localenv.fname) {
_FP_free (result->filename); _FP_free (result->filename);
@ -2108,7 +2324,7 @@ ScanPart (FILE *datei, char *fname, int *errcode)
*errcode = UURET_NOMEM; *errcode = UURET_NOMEM;
} }
else if ((result->uudet==QP_ENCODED || result->uudet==PT_ENCODED) && else if ((result->uudet==QP_ENCODED || result->uudet==PT_ENCODED) &&
result->filename==NULL) { result->filename==NULL && uu_handletext) {
sprintf (line, "%04d.txt", ++mimseqno); sprintf (line, "%04d.txt", ++mimseqno);
if ((result->filename = _FP_strdup (line)) == NULL) if ((result->filename = _FP_strdup (line)) == NULL)
*errcode = UURET_NOMEM; *errcode = UURET_NOMEM;
@ -2234,9 +2450,22 @@ ScanPart (FILE *datei, char *fname, int *errcode)
result->uudet = QP_ENCODED; result->uudet = QP_ENCODED;
else if (_FP_stristr (localenv.ctenc, "base64") != NULL) else if (_FP_stristr (localenv.ctenc, "base64") != NULL)
result->uudet = B64ENCODED; 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 || else if (_FP_stristr (localenv.ctype, "multipart") != NULL ||
_FP_stristr (localenv.ctype, "message") != NULL) _FP_stristr (localenv.ctype, "message") != NULL)
result->uudet = PT_ENCODED; 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 { else {
memset (&localenv, 0, sizeof (headers)); memset (&localenv, 0, sizeof (headers));
@ -2262,7 +2491,6 @@ ScanPart (FILE *datei, char *fname, int *errcode)
} }
else if (result->uudet != 0) { else if (result->uudet != 0) {
hcount = lcount = 0; hcount = lcount = 0;
prevpos = ftell (datei); prevpos = ftell (datei);
if (_FP_stristr (localenv.ctype, "message") != NULL && if (_FP_stristr (localenv.ctype, "message") != NULL &&
@ -2274,17 +2502,11 @@ ScanPart (FILE *datei, char *fname, int *errcode)
while (!feof (datei)) { while (!feof (datei)) {
if (_FP_fgets (line, 255, datei) == NULL) if (_FP_fgets (line, 255, datei) == NULL)
break; break;
if (!IsLineEmpty (line)) {
fseek (datei, preheaders, SEEK_SET);
line[255] = '\0'; line[255] = '\0';
if (!IsLineEmpty (line)) {
break; break;
} }
} }
if (_FP_fgets (line, 255, datei) == NULL) {
_FP_free (result);
return NULL;
}
line[255] = '\0';
while (!feof (datei) && !IsLineEmpty (line)) { while (!feof (datei) && !IsLineEmpty (line)) {
if (IsKnownHeader (line)) if (IsKnownHeader (line))
@ -2388,6 +2610,8 @@ ScanPart (FILE *datei, char *fname, int *errcode)
result->subject = _FP_strdup (sstate.envelope.subject); result->subject = _FP_strdup (sstate.envelope.subject);
} }
result->partno = sstate.envelope.partno; result->partno = sstate.envelope.partno;
if (sstate.envelope.partno == 1)
result->begin = 1;
result->maxpno = sstate.envelope.numparts; result->maxpno = sstate.envelope.numparts;
result->flags = FL_PARTIAL | result->flags = FL_PARTIAL |
((res==1 || uu_fast_scanning) ? FL_PROPER : 0) | ((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. * 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 && if (sstate.isfolder && sstate.ismime &&
sstate.mimestate == MS_BODY && sstate.mimestate == MS_BODY &&
(_FP_stristr (sstate.envelope.ctenc, "quoted-printable") != NULL || (_FP_stristr (sstate.envelope.ctenc, "quoted-printable") != NULL ||
_FP_stristr (sstate.envelope.ctenc, "base64") != 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) if (sstate.envelope.subject)
result->subject = _FP_strdup (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; result->uudet = QP_ENCODED;
else if (_FP_stristr (sstate.envelope.ctenc, "base64") != NULL) else if (_FP_stristr (sstate.envelope.ctenc, "base64") != NULL)
result->uudet = B64ENCODED; 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 || 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; 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 * If this is Quoted-Printable or Plain Text, just try looking
* for the next message header. If uu_fast_scanning, we know * for the next message header. If uu_fast_scanning, we know
* there won't be more headers. * 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) { if (result->uudet != 0 && uu_fast_scanning) {
/* do nothing */ /* do nothing */
@ -2475,8 +2720,43 @@ ScanPart (FILE *datei, char *fname, int *errcode)
} }
else if (result->uudet != 0) { else if (result->uudet != 0) {
hcount = lcount = 0; hcount = lcount = 0;
prevpos = ftell (datei); 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)) { while (!feof (datei)) {
if (_FP_fgets (line, 255, datei) == NULL) if (_FP_fgets (line, 255, datei) == NULL)
break; break;
@ -2592,7 +2872,6 @@ ScanPart (FILE *datei, char *fname, int *errcode)
return result; return result;
} }
#ifndef MORE_MIME
/* /*
* Some files have reduced headers, and what should be a multipart * Some files have reduced headers, and what should be a multipart
* message is missing the proper Content-Type. If the first thing * 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 * we know that sstate.envelope.boundary is NULL, or we wouldn't
* be here! * 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); prevpos = ftell (datei);
while (!feof (datei)) { while (!feof (datei)) {
if (_FP_fgets (line, 255, datei) == NULL) { if (_FP_fgets (line, 255, datei) == NULL) {
@ -2650,7 +2931,6 @@ ScanPart (FILE *datei, char *fname, int *errcode)
} }
fseek (datei, prevpos, SEEK_SET); fseek (datei, prevpos, SEEK_SET);
} }
#endif
/* /*
* Hmm, we're not in a ''special'' state, so it's more or less * 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- * 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 * file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may
* contacted by his email address, fp@informatik.uni-frankfurt.de * be contacted at fp@fpx.de
* *
* This program is free software; you can redistribute it and/or modify * 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 * 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_SOURCE 1
#define S_NOT_OPEN_TARGET 2 #define S_NOT_OPEN_TARGET 2
#define S_NOT_OPEN_FILE 3 #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- * 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 * file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may
* contacted by his email address, fp@informatik.uni-frankfurt.de * be contacted at fp@fpx.de
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -477,9 +477,3 @@ UUSmerge (int pass)
return flag; return flag;
} }
/*****************************************************************************
+ Frank Pilhofer fp@informatik.uni-frankfurt.de +
+---------------------------------------------------------------------------+
| Department of Computer Sciences * University of Frankfurt / Main, Germany |
*****************************************************************************/