--- Configure +++ Configure 1995/09/22 14:08:22 @@ -2670,19 +2670,19 @@ : where do we get termlib routines from echo " " -xxx=`./loc libcurses.a x $libpth` +xxx=`./loc libncurses.a x $libpth` case "$xxx" in /*) ar t $xxx >grimble if $contains tputs.o grimble >/dev/null 2>&1; then - termlib='-lcurses' + termlib='-lncurses' d_havetlib="$define" echo "Terminfo library found." >&4 elif $test "x`$uname 2>/dev/null`" = xAIX; then # Ok, do the AIX shr.o fun thing /usr/ccs/bin/nm -en $xxx 2>/dev/null >grimble if $contains '^tputs .*|extern|' grimble >/dev/null 2>&1; then - termlib='-lcurses' + termlib='-lncurses' d_havetlib="$define" echo "AIX Terminfo library found." >&4 else --- README.linux +++ README.linux 1995/09/22 14:13:44 @@ -0,0 +1,70 @@ +Fetch the original source code, patch it with "patch -s -p0 < this_patch". + +To compile trn, use the following commands: (Configure gives me correct default +answers for my machine. You may have to use different ones for your machine.) + ./Configure -f hints/linux.sh + make + +Do "make install" to install everything. That's all. + +Most patches are from Olaf Titz and below is a description from him. +Please email first to me, so that Olaf won't get email about bugs that +are caused by things that I have changed. + +Please also email me further patches that I could include here. + +Thanks, + +Florian La Roche + +-------------------------------------------------------------------------- +Newsgroups: alt.sources +From: Olaf Titz +Subject: trn 3.6 quoted-printable/RFC1522 patch +Date: 05 Sep 1995 20:50:21 GMT +Message-ID: + +Archive-name: trn36-q3.dif +Submitted-by: Olaf Titz + +Patch for trn 3.6 to enable quoted-printable article and +RFC 1522 header decoding. + +Features: + +- Articles with "Content-Transfer-Encoding: quoted-printable" are + decoded while displaying. If charset substitution is active, this is + done too. The charset used is still fixed at ISO-8859-1. For + replying the decoding is done too. For storing, MIMESTORE is used. + (Encoding base64 still activates external MIME viewer.) + +- Header lines with RFC 1522 encoded-words in Q and B encodings are + decoded while displaying. The charset is assumed as ISO-8859-1 + regardless of the actual header. This affects header lines read from + thread and overview databases, too. (Note: From lines in thread + database are limited to 16 characters, which is too small for + encoded-words, but the decoding can be done by mthreads, see related + mthreads patch.) + +Other enhancements: + +- Charset substitutions "a" and "m" are done in displayed header lines too. + +- %s interpolation strips nonstandard "Re(n)", "Re^n" forms. + +- Nasty TeX decoding bug fixed. + +Remaining bugs: + +- Line count sometimes goes wrong - lines get swallowed in display. + (Press v to fix.) I still haven't found the cause. + +- TeX decoding shifts \ and " across lines. + +- Decoder source is messy and needs restructuring. + +July 1995 Olaf.Titz@inka.de + +---------------------------------------------------------------------------- + +Florian La Roche --- art.c +++ art.c 1995/09/22 14:08:22 @@ -146,6 +146,9 @@ #if defined(MIMESHOW) || defined(MIMESTORE) mime_article = FALSE; #endif +#ifdef QPDECODE + art_encoding = 'p'; +#endif #ifndef USE_NNTP if (fstat(fileno(artfp),&filestat)) /* get article file stats */ @@ -315,6 +318,14 @@ else if (in_header == CONTXFER_LINE) mime_article = mime_article || nonprint(art_buf+27); } +#else +#ifdef QPDECODE + /* just interpret the encoding */ + else if (in_header == CONTXFER_LINE) { + int nonprint _((char *)); + nonprint(art_buf+27); + } +#endif #endif } if (in_header == SUBJ_LINE && @@ -1194,6 +1205,10 @@ return 0; /* no charset, was text/plain */ } +#endif + +#if defined(MIMESHOW) || defined(MIMESTORE) || defined(QPDECODE) + /* return true if this isn't "7bit", "8bit", or "binary" */ int @@ -1208,6 +1223,17 @@ s += 4; else if (strncasecmp(s, "binary", 6) == 0) s += 6; +#ifdef QPDECODE + else if (strncasecmp(s, "quoted-printable", 16) == 0) { + art_encoding = 'q'; + return 0; } +#if 0 +/* Not yet */ + else if (strncasecmp(s, "base64", 6) == 0) { + art_encoding = 'b'; + return 0; } +#endif +#endif else return 1; return !(*s == '\0' || isspace(*s) || *s == ';' || *s == '('); /*)*/ --- artio.c +++ artio.c 1995/09/22 14:08:22 @@ -23,6 +23,7 @@ #include "bits.h" #include "final.h" #include "ngdata.h" +#include "charsubst.h" #include "INTERN.h" #include "artio.h" @@ -97,3 +98,50 @@ } return artfp; /* and return either fp or NULL */ } + +#ifdef QPDECODE + +char * +readart(s, limit) +char *s; +int limit; +{ + if (in_header || (art_encoding=='p')) { /* Plain encoded body */ +#ifdef USE_NNTP + return nntp_readart(s, limit); +#else + return fgets(s, limit, artfp); +#endif + } else if (art_encoding=='q') { /* qp encoded body */ + register char *y=s; + int l; + readline: +#ifdef USE_NNTP + y=nntp_readart(y, limit); +#else + y=fgets(y, limit, artfp); +#endif + if (!y) + return Nullch; + l=strlen(y); + if (y[--l]=='\n') { + while (y[--l]==' '||y[l]=='\t'); /* kill trailing whitespace */ + if (y[l]=='=') { + /* continuation line */ + y+=l; limit-=l; + if (limit>1) + goto readline; + } + y[++l]='\n'; y[++l]='\0'; + } + decode_qp(s); +#if 0 +/* Not yet */ + } else if (art_encoding=='b') { /* b64 encoded body */ +#endif + } else + return Nullch; /* Uh? */ + return s; +} + +#endif --- artio.h +++ artio.h 1995/09/22 14:08:22 @@ -26,12 +26,20 @@ void artio_init _((void)); FILE *artopen _((ART_NUM)); /* open an article unless already opened */ +#ifdef QPDECODE +char *readart _((char*,int)); +#else #ifdef USE_NNTP -# define seekart(pos) nntp_seekart(pos) # define readart(s,len) nntp_readart(s,len) +#else +# define readart(s,len) fgets(s,len,artfp) +#endif +#endif + +#ifdef USE_NNTP +# define seekart(pos) nntp_seekart(pos) # define tellart() nntp_tellart() #else # define seekart(pos) fseek(artfp, pos, 0) -# define readart(s,len) fgets(s,len,artfp) # define tellart() ftell(artfp) #endif --- charsubst.c +++ charsubst.c 1995/09/22 14:08:22 @@ -72,6 +72,7 @@ texchar = (char)c; break; } else if (texchar == '\\') { + texchar = '\0'; if (outputok) putchar('\\'); if (limit == 1) { @@ -154,9 +155,16 @@ strcharsubst(inb, outb) char *inb, *outb; { + int t; switch(*charsubst) { + case 'm': + t = 1; + goto doconvert; case 'a': - Latin1toASCII((unsigned char*)inb, (unsigned char*)outb, 2); + t = 2; + /* FALL THROUGH */ + doconvert: + Latin1toASCII((unsigned char*)inb, (unsigned char*)outb, t); break; default: strcpy(outb, inb); @@ -234,6 +242,109 @@ *asc++ = *iso++; } *asc = 0; +} + +#endif + +#ifdef QPDECODE + +/* MIME decoders */ + +/* These routines do decoding of strings in-place. The encoding + guarantees that the result may be shortened but not lengthened. + qp: transforms quoted-printable =xx patterns + b64: unpacks base64 - note null termination + 1522: decode rfc1522 =?charset?e?value?= patterns + Charset parameters are ignored. */ + +#define hexdigit(x) ((x>='0'&&x<='9')?(x-'0'):((x>='A'&&x<='F')?(x-'A'+10):0)) + +void +decode_qp(src) +char *src; +{ + register char c, c0, c1; + register char *d=src; + while ((c=*src++)) { + if ((c=='=') && (c0=toupper(src[0])) && (c1=toupper(src[1]))) { + *d++ = 16*hexdigit(c0)+hexdigit(c1); + src+=2; + } else { + *d++ = c; + } + } + *d='\0'; +} + +/* base64 encoding charset */ +static char base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static void +store24(d, c) +char **d; +char *c; +{ + *(*d)++=(c[0]<<2)+(c[1]>>4); + *(*d)++=((c[1]<<4)&255)+(c[2]>>2); + *(*d)++=((c[2]<<6)&255)+c[3]; +} + +void +decode_b64(src) +char *src; +{ + char c0, c[4], *p; + int i=0; + char *d=src; + while (c0 = *src++) { + if (c0=='=') + break; /* a = symbol is end padding */ + if ((p=strchr(base64, c0))) { + c[i++]=p-base64; + if (i==4) { + store24(&d, c); + i=0; + } + } /* unknown symbols are ignored */ + } + if (i>0) { + for(;i<4;c[i++]=0); /* will leave padding nulls - don't matter here */ + store24(&d, c); + } + *d=0; +} + + +void +decode_1522(src) +char *src; +{ + register char c, e; + register char *d=src, *p1, *p2; + while ((c=*src++)) { + if (((c=='=') && (*src=='?')) && + (p1=strchr(src+1, '?')) && + (e=toupper(*++p1), e=='Q'||e=='B') && + (*++p1=='?') && + (p2=strstr(++p1, "?="))) { + /* this is rfc1522 encoded-word, ignore the charset by now */ + for (src=p1; src= string_end) break; - *author_ptr++ = string_ptr; + *author_ptr = string_ptr; string_ptr += strlen(string_ptr) + 1; +#ifdef QPDECODE + decode_1522(*author_ptr); + /* This is of no point due to the 16 char limit, but leave it in + to show how things _should_ be :-) */ +#endif + author_ptr++; } subject_strings = string_ptr; @@ -284,15 +291,26 @@ for (count = total.subject; count; count--) { int len; +#ifdef QPDECODE + int len0; +#endif ARTICLE arty; if (string_ptr >= string_end) break; +#ifdef QPDECODE + len0 = strlen(string_ptr); + decode_1522(string_ptr); +#endif len = strlen(string_ptr); arty.subj = 0; set_subj_line(&arty, string_ptr, len); if (len == 72) arty.subj->flags |= SF_SUBJTRUNCED; +#ifdef QPDECODE + string_ptr += len0 + 1; +#else string_ptr += len + 1; +#endif *subj_ptr++ = arty.subj; } if (count || string_ptr != string_end) { --- rt-ov.c +++ rt-ov.c 1995/09/22 14:08:22 @@ -22,6 +22,7 @@ #include "rt-process.h" #include "rt-util.h" #include "overview.h" +#include "charsubst.h" #include "INTERN.h" #include "rt-ov.h" @@ -267,6 +268,9 @@ break; } *cp++ = '\0'; +#ifdef QPDECODE + decode_1522(fields[nf]); +#endif } if (!article->subj) --- rt-wumpus.c +++ rt-wumpus.c 1995/09/22 14:08:22 @@ -18,6 +18,7 @@ #include "backpage.h" #include "rthread.h" #include "rt-select.h" +#include "charsubst.h" #include "INTERN.h" #include "rt-wumpus.h" @@ -253,8 +254,13 @@ char ch; /* Make a modifiable copy of the line */ +#ifdef CHARSUBST + buf = safemalloc(2*strlen(orig_line) + 2); /* yes, I mean "2" */ + strcharsubst(orig_line, buf); +#else buf = safemalloc(strlen(orig_line) + 2); /* yes, I mean "2" */ strcpy(buf, orig_line); +#endif line = buf; /* Change any embedded control characters to spaces */