Apply this patch in your trn 3 source directory with the command: patch -p /tmp/c1$$ <&4 -c "$ans";; esac ;; Index:NEW @@ -5,4 +5,36 @@ incompatibilities between trn 2.5 and trn 3.0. +Changes from trn 3.2 to trn 3.3: + + o Newsetup now looks for NEWSLIB/subscriptions for a default list + of groups to subscribe the user to. If the file doesn't exist + the NNTP version will attempt to grab it via the LIST SUBSCRIPTIONS + command (available in INN and some nntp patches). + [HINT: if you want your subscription file to default to all + groups in the active file, link your subscription file to your + active file -- trn will strip the info past the first space + when it processes the .newsrc.] + o The file newsnews will now default to a simple version update + message instead of a welcome-to trn message (which is now provided + by the newsetup file when creating a new .newsrc for a user). + I still encourage you to install your own custom newsnews + when trn is updated (and trn still doesn't install newsnews + automatically -- you have to make this decision for your self). + o Redirected and disabled groups (marked by '=' or 'x' in the active + file) are now handled better, allowing you to read any remaining + articles after a group gets redirected or disabled and warning you + to either start using the new group name or that the group will + not be receiving any new news. + o Mime support is now prompted for in Configure and your system's + display/store commands are remembered. We also handle a continued + Content-Type header correctly now. + o The tick (') interp modifier will generate a tick-quoted string + with all ticks inside the string quoted. For example, %'s might + generate (INCLUDING the "'"s) 'Ticks aren\'t a problem.' + o If the environment variable FAST_PNEWS == y Pnews skips the "Are + you sure?" question and the "include file" prompt. You can put + -EFAST_PNEWS=y in the global INIT file, if you so desire. + o Various bug fixes. + Changes from trn 3.1 to trn 3.2: Index:Pnews.SH @@ -249,4 +249,7 @@ esac +case "$FAST_PNEWS" in +y*) ;; +*) # tell them what we think they are doing... !DIST! case $dist in @@ -315,4 +318,6 @@ esac done +;; +esac # run getactive in the background, if necessary @@ -321,5 +326,11 @@ fi -file=h +case "$FAST_PNEWS" in +y*) file='' + $echo "" >> $tmpart + state=edit + ;; +*) file=h;; +esac while $test "X$file" = Xh ; do $echo "" @@ -413,5 +424,6 @@ check) # wait for possible background getactive - wait + $test "$cmdlist" && wait + # warn about long lines, malformed headers, misspelled newsgroups $artcheck $tmpart 79 $newsgroups $active Index:addng.c @@ -254,5 +254,5 @@ long tot; - if (!nntp_group(ngnam,0)) + if (!nntp_group(ngnam,-1)) return 0; /* not a real group */ (void) sscanf(ser_line,"%*d%ld",&tot); Index:art.c @@ -79,5 +79,5 @@ } -#ifdef METAMAIL +#ifdef MIME_SUPPORT #define VERY_LONG_STRING 200 int @@ -86,9 +86,9 @@ int code = 1; - if (!getenv("NOMETAMAIL")) { + if (!getenv("NOMIME")) { char oldmode = mode; interp(cmd_buf,(sizeof cmd_buf),getval("MIMESHOW",MIMESHOW)); - fputs("Display MIME article with metamail? [yn]",stdout); + fputs("Process MIME article? [yn]",stdout); fflush(stdout); eat_typeahead(); @@ -103,6 +103,10 @@ printcmd(); #endif - putchar('\n') FLUSH; + carriage_return(); + erase_eol(); /* erase the prompt */ + carriage_return(); /* Resets kernel's tab column counter to 0 */ if (*buf == 'y') { + putchar('\n'); + fflush(stdout); termlib_reset(); resetty(); @@ -134,5 +138,5 @@ char oldmode = mode; char *ctime(); -#ifdef METAMAIL +#ifdef MIME_SUPPORT bool tried_display_mime = FALSE; #endif @@ -141,5 +145,5 @@ #endif -#ifdef METAMAIL +#ifdef MIME_SUPPORT mime_article = FALSE; #endif @@ -296,6 +300,6 @@ } #endif -#ifdef METAMAIL - else if (in_header == CONTENT_LINE) { +#ifdef MIME_SUPPORT + else if (in_header == CONTENT_LINE && !isspace(*art_buf)) { mime_article = nontext(art_buf+14); } @@ -329,5 +333,5 @@ } else { /* just a normal line */ -#ifdef METAMAIL +#ifdef MIME_SUPPORT if (mime_article && do_hiding && !tried_display_mime) { if (display_mime() == 0) @@ -1004,5 +1008,5 @@ #endif -#ifdef METAMAIL +#ifdef MIME_SUPPORT int nontext(content_type) Index:artcheck.c @@ -147,6 +147,6 @@ } } + fclose(fp_active); } - fclose(fp_active); if (fp_ng != NULL) { ngleft = ngcnt; @@ -172,6 +172,6 @@ } } + fclose(fp_ng); } - fclose(fp_ng); for (i = 0; i < ngcnt; i++) { if (!foundactive[i]) { Index:artsrch.c @@ -216,9 +216,10 @@ if (howmuch != ARTSCOPE_SUBJECT) { *s++ = scopestr[howmuch]; - if (howmuch == ARTSCOPE_ONEHDR) + if (howmuch == ARTSCOPE_ONEHDR) { safecpy(s,srchhdr,LBUFLEN-(s-saltbuf)); - s = index(s,':'); - if (!s) - s = saltbuf+LBUFLEN-2; + s = index(s,':'); + if (!s) + s = saltbuf+LBUFLEN-2; + } } *s++ = ':'; Index:cache.c @@ -70,4 +70,8 @@ grow_cache(lastart); rc_to_bits(); + if (sel_mode == SM_ARTICLE) + set_selector(sel_mode, sel_artsort); + else + set_selector(sel_threadmode, sel_threadsort); thread_grow(); return; Index:cache.h @@ -90,5 +90,5 @@ #define Nullsubj Null(SUBJECT*) -#define was_read(a) ((a) >= absfirst && (article_ptr(a)->flags & AF_READ)) +#define was_read(a) ((a) < absfirst || (article_ptr(a)->flags & AF_READ)) /* These must never use their args more than once in the definition */ Index:common.h @@ -298,5 +298,4 @@ #define EDIT_DISTANCE /* Allow -G to specify a fuzzy 'go' command */ #undef VALIDATE_XREF_SITE /* are xrefs possibly invalid? */ -#undef METAMAIL /* use metamail to process mime articles */ /* some dependencies among options */ @@ -466,17 +465,4 @@ #endif -#ifdef METAMAIL -/* default MIME extraction program */ -# ifndef MIMESTORE -# define MIMESTORE "/usr/local/bin/mh/mhn -store -auto -file " -# endif - -/* default MIME show program */ -# ifndef MIMESHOW -# define MIMESHOW "metamail -e -p -m \"trn %s\" %A" -# endif -#endif - - /* path to default editor */ #ifndef DEFEDITOR @@ -618,5 +604,5 @@ #endif -#ifdef METAMAIL +#ifdef MIME_SUPPORT # ifndef EXMIMESAVER # define EXMIMESAVER "%e %A" @@ -738,15 +724,25 @@ #ifdef HAS_STRCHR +# ifndef index # define index strchr +# endif +# ifndef rindex # define rindex strrchr +# endif #endif #ifdef HAS_MEMCMP +# ifndef bcmp # define bcmp(s,d,l) memcmp((s),(d),(l)) +# endif #endif #ifdef HAS_MEMCPY +# ifndef bcopy # define bcopy(s,d,l) memcpy((d),(s),(l)) +# endif #endif #ifdef HAS_MEMSET +# ifndef bzero # define bzero(s,l) memset((s),0,(l)) +# endif #endif @@ -761,5 +757,5 @@ /* various things of type char */ -#ifdef SUPPLIMENT_STRING_H +#ifdef SUPPLEMENT_STRING_H char *index(); char *rindex(); @@ -910,5 +906,5 @@ #endif -#ifdef METAMAIL +#ifdef MIME_SUPPORT EXT bool mime_article INIT(FALSE); #endif Index:config.h.SH @@ -290,4 +290,18 @@ #$d_internet INTERNET /**/ +/* MIME_SUPPORT: + * This symbol, if defined, indicates mime articles should be processed + * by an external program. + */ +/* MIMESHOW: + * This symbol points to the program to run to show a mime article. + */ +/* MIMESTORE: + * This symbol points to the program to run to store a mime article. + */ +#$d_mime MIME_SUPPORT /**/ +#$d_mime MIMESHOW "$mimeshow" +#$d_mime MIMESTORE "$mimestore" + /* USE_NNTP: * This symbol, if defined, indicates that NNTP should be used. Index:getactive.c @@ -32,5 +32,5 @@ if (argc < 2 || argc > 3) { - fprintf(stderr, "Usage: getactive [active|distributions|newsgroups] filename\n"); + fprintf(stderr, "Usage: getactive [active|distributions|newsgroups|subscriptions] filename\n"); exit(1); } Index:head.c @@ -202,6 +202,10 @@ if (!ap->subj) { +#if 0 uncache_article(ap,FALSE); return; +#else + set_subj_line(ap,"Subject: ",15); +#endif } @@ -223,8 +227,10 @@ free(references); artp = artp_hold; + check_poster(ap); } - } else if (!(ap->flags & AF_CACHED)) + } else if (!(ap->flags & AF_CACHED)) { cache_article(ap); - check_poster(ap); + check_poster(ap); + } } @@ -360,12 +366,14 @@ *s = '\0'; priornum = artnum-1; - lastnum = artnum + PREFETCH_SIZE - 1; - if (lastnum > lastart) - lastnum = lastart; - if ((cached = (htype[which_line].ht_flags & HT_CACHED)) != 0) + if ((cached = (htype[which_line].ht_flags & HT_CACHED)) != 0) { + lastnum = artnum + PREFETCH_SIZE - 1; + if (lastnum > lastart) + lastnum = lastart; sprintf(ser_line,"XHDR %s %ld-%ld",htype[which_line].ht_name, artnum,lastnum); - else + } else { + lastnum = artnum; sprintf(ser_line,"XHDR %s %ld",htype[which_line].ht_name,artnum); + } nntp_command(ser_line); if (nntp_check(TRUE) == NNTP_CLASS_OK) { Index:head.h @@ -88,5 +88,5 @@ {"anpa", 0, 0, 4, HT_HIDE }, {"codes", 0, 0, 5, HT_HIDE }, -#ifdef METAMAIL +#ifdef MIME_SUPPORT {"content-type", 0, 0, 12, HT_MAGIC }, #else Index:hints/sgi.sh @@ -1,3 +1,3 @@ d_voidsig=define -d_novfork=undef +d_novfork=define d_sigblock=undef Index:intrp.c @@ -439,4 +439,5 @@ bool lastcomp = FALSE; bool re_quote = FALSE; + bool tick_quote = FALSE; bool address_parse = FALSE; bool comment_parse = FALSE; @@ -453,4 +454,5 @@ lastcomp = FALSE; re_quote = FALSE; + tick_quote = FALSE; address_parse = FALSE; comment_parse = FALSE; @@ -467,4 +469,7 @@ re_quote = TRUE; break; + case '\'': + tick_quote = TRUE; + break; case '>': address_parse = TRUE; @@ -502,10 +507,11 @@ if (art_howmuch != ARTSCOPE_SUBJECT) { *s++ = scopestr[art_howmuch]; - if (art_howmuch == ARTSCOPE_ONEHDR) + if (art_howmuch == ARTSCOPE_ONEHDR) { safecpy(s,art_srchhdr, (sizeof scrbuf) - (s-scrbuf)); - s = index(s,':') + 1; - if (!s) - s = scrbuf+(sizeof scrbuf)-1; + s = index(s,':') + 1; + if (!s) + s = scrbuf+(sizeof scrbuf)-1; + } } } @@ -985,5 +991,5 @@ *dest++ = *s++ | i; } - } else if (re_quote) { + } else if (re_quote || tick_quote) { /* put a backslash before regexp specials while copying. */ if (s == dest) { @@ -992,8 +998,14 @@ s = scrbuf; if (i > sizeof scrbuf) /* we truncated, ack! */ - destsize += i - sizeof scrbuf; + abort_interp(); + } + if (tick_quote) { + *dest++ = '\''; + if ((destsize -= 2) <= 0) + abort_interp(); } while (*s) { - if (index(regexp_specials, *s)) { + if ((re_quote && index(regexp_specials, *s)) + || (tick_quote && *s == '\'')) { if (--destsize <= 0) abort_interp(); @@ -1002,4 +1014,6 @@ *dest++ = *s++; } + if (tick_quote) + *dest++ = '\''; } else { /* straight copy. */ Index:ndir.h @@ -19,5 +19,7 @@ #ifdef I_DIRENT #include +#ifndef direct #define direct dirent +#endif #else #ifdef I_SYS_NDIR Index:newsetup.1 @@ -51,12 +51,12 @@ The .I newsetup -program creates a new .newsrc file containing all of the currently active -newsgroups. -It tries to put them in a reasonable order, i.e. local newsgroups earlier, -but you'll probably want to change the ordering anyway (if you use -.IR rn ) -in order to put interesting newsgroups first. +program creates a new .newsrc file containing an list of recommended +newsgroups for the first time user. +If your news admin has specified such a list (usually in the file +NEWSLIB/subscriptions) trn will use that as a default for your .newsrc. +Otherwise you get a ridiculously small list that you'll want to add to +using the \*(L"a pattern\*(R" command in trn (such as \*(L"a linux\*(R"). If you already have a .newsrc, it will be backed up with the name -\*(L".oldnewsrc\*(R". +\*(L".newsrc-old\*(R". .SH ENVIRONMENT .IP DOTDIR 8 @@ -71,9 +71,9 @@ Your home directory if HOME is undefined. .SH FILES -/usr/lib/news/active or a reasonable facsimile +/usr/lib/news/subscriptions or a reasonable facsimile .br ${DOTDIR-{$HOME-$LOGDIR}}/.newsrc .SH SEE ALSO -rn(1), newsrc(5) +trn(1), rn(1), newsrc(5) .SH DIAGNOSTICS .SH BUGS Index:newsetup.SH @@ -23,90 +23,85 @@ : syntax: newsetup -: System dependencies -: You will want to change the definitions below to reflect the distribution -: areas around you. If you have more areas than this you will need to modify -: the sed below. - -locorg="$locdist" -organization="$orgdist" -city="$citydist" -state="$statedist" -cntry="$cntrydist" -cont="$contdist" -#NORMALactive="${active-/usr/lib/news/active}" -#NNTPactive="/tmp/active.\$\$" - -dotdir="\${DOTDIR-\${HOME-\$LOGDIR}}" -newsrc="\${NEWSRC-\$dotdir/.newsrc}" -$rm -f \$newsrc-old -$echo "Creating \$newsrc to be used by news programs." -#NNTPrnlib=$privlib -#NNTPcase \$rnlib in -#NNTP~*) rnlib=\`$filexp \$rnlib\` ;; -#NNTPesac -#NNTPif \$rnlib/getactive ACTIVE \$active; then -#NNTP true; -#NNTPelse -#NNTP exit 1; -#NNTPfi -#NORMALcase \$active in -#NORMAL~*) active=\`$filexp \$active\` ;; -#NORMALesac - -if $test -s \$newsrc ; then - $echo "Saving your current \$newsrc as \$newsrc-old..." - $mv -f \$newsrc \$newsrc-old -fi +case $d_portable in +define) + # where recordings, distributions and moderators are kept + lib=\`$filexp $newslib\` + # where important rn things are kept + rnlib=\`$filexp $privlib\` + ;; +undef) + # where recordings, distributions and moderators are kept + lib="$newslib" + # where important rn things are kept + rnlib="$privlib" + ;; +esac -: newsrc order determined here +test=${test-test} +echo=${echo-echo} +cat=${cat-cat} +mv=${mv-mv} +rm=${rm-rm} -$sed <\$active ' - /^to\./d - / [^mny][^ ]*$/d - s/ .*// - s/^/ / - s/^ '\$locorg'\./01&/ - s/^ '\$organization'\./02&/ - s/^ '\$city'\./03&/ - s/^ '\$state'\./04&/ - s/^ '\$cntry'\./05&/ - s/^ '\$cont'\./06&/ - s/^ news\./07&/ - s/^ comp\./08&/ - s/^ sci\./09&/ - s/^ rec\./10&/ - s/^ soc\./11&/ - s/^ talk\./13&/ - s/^ control\$/14&/ - s/^ junk\$/14&/ - s/^ test\$/14&/ - /\.test\$/s/^[0-9]*/14/ - s/^ .*\./12&/ - s/^ /00&/ -' | -$sort -u | -$sed ' - /^14 /!s/\$/:/ - /^14 /s/\$/!/ - s/^[0-9][0-9] // -' >\$newsrc +!GROK!THIS! +$cat >>newsetup <<'!NO!SUBS!' +dotdir="${DOTDIR-${HOME-$LOGDIR}}" +newsrc="${NEWSRC-$dotdir/.newsrc}" +tmp="${TMPDIR-/tmp}" -#NNTP$rm -f \$active +subs="$lib/subscriptions" +tmpsubs="$tmp/trnsubs.$$" $cat <<'EOH' -Done. + +Welcome to trn. Here's some important things to remember: -If you have never used the news system before, you may find the articles -in news.announce.newusers to be helpful. There is also a manual entry for rn. + o Trn is an extension of rn and has a similar command syntax. + o To access all the new features, specify the options -x and -X. These + options MAY be on by default, but it won't hurt to be redundant. + o Single-character commands don't require a carriage return -- only + commands that let you type in an argument. + o At ANY prompt, you may type 'h' for help. There are many different help + menus, depending on the context. Also, typing h in the middle of a + multi-character command will list escape substitutions. + o Typing a space to any prompt means to do the normal thing. You could + spend all day reading news and never hit anything but the space bar. + o If you have never used the news system before, you may find the articles + in news.announce.newusers to be helpful. + o Please consult the man page for complete information. -To get rid of newsgroups you aren't interested in, use the 'u' command. -Type h for help at any time while running rn. EOH -!GROK!THIS! -case "$d_nntp" in -define) sed < newsetup -e '/^#NNTP/s/^#NNTP//' -e '/^#NORMAL/d' > newsetup.new ;; -*) sed < newsetup -e '/^#NNTP/d' -e '/^#NORMAL/s/^#NORMAL//' > newsetup.new ;; -esac -mv newsetup.new newsetup + +$rm -f $newsrc-old +$echo "Creating $newsrc to be used by news programs." + +if $test -s "$newsrc"; then + $echo "Saving your current one as $newsrc-old..." + $mv -f $newsrc $newsrc-old +fi + +if $test -r $subs; then + cp $subs $newsrc +else + if $test -r $rnlib/getactive; then + $rnlib/getactive subscriptions $tmpsubs >/dev/null 2>&1 + fi + if $test -s $tmpsubs; then + cp $tmpsubs $newsrc + else + $cat <$newsrc +news.announce.newusers: +EOM + fi + $rm -f $tmpsubs +fi + +$cat <<'EOH' +Done. + +To add new group use "a pattern" or "g newsgroup.name". To get rid of +newsgroups you aren't interested in, use the 'u' command. +EOH +!NO!SUBS! $eunicefix newsetup chmod 755 newsetup Index:newsnews.SH @@ -7,18 +7,9 @@ *** NEWS NEWS *** -Welcome to trn. There are more options to trn than you want to think about, -so we won't list them here. If you want to find out about them, read the -manpage. There are some important things to remember, though: +Welcome to trn 3.3. This is a minor update from 3.2 with some bug fixes +and a few improvements. Trn is "threaded read news", based on rn. - * Trn is an extension of rn. Where possible, the command syntax is the same. - * To access all the new features, specify the options -x and -X. These - options MAY be on by default, but it won't hurt to be redundant. - * Single-character commands don't require a carriage return -- only - commands that let you type in an argument. - * At ANY prompt, you may type 'h' for help. There are many different help - menus, depending on the context. Also, typing h in the middle of a - multi-character command will list escape substitutions. - * Typing a space to any prompt means to do the normal thing. You could - spend all day reading news and never hit anything but the space bar. +You can type 'h' at any prompt to display a summary of the commands that +are available. This message will not be displayed again unless it is updated with new Index:ng.c @@ -220,5 +220,5 @@ goto article_level; } - count_subjects(CS_NORM); + count_subjects(CS_RETAIN); for (i=last_cached+1, ap=article_ptr(i); i<=lastart; i++, ap++) if (!(ap->flags & AF_READ)) @@ -253,5 +253,10 @@ (long)article_count,article_count==1?nullstr:"s"); } - else if (!forcelast) + if (redirected) { + if (redirected == nullstr) + printf("\n\n** This group has been disabled by your news admin **"); + else + printf("\n\n** Please start using %s **", redirected); + } else if (!article_count && !forcelast) goto cleanup; /* actually exit newsgroup */ mode = 'e'; Index:ngdata.c @@ -252,15 +252,30 @@ abs1st[num] = (ART_NUM)first; if (!in_ng) { + if (redirected) { + if (redirected != nullstr) + free(redirected); + redirected = Nullch; + } switch (ch) { - case 'n': moderated = getval("NOPOSTRING"," (no posting)"); break; - case 'm': moderated = getval("MODSTRING", " (moderated)"); break; - /* This shouldn't even occur. What are we doing in a non-existent - group? Disallow it. */ - case 'x': return TR_BOGUS; - /* what should be done about refiled groups? rn shouldn't even - be in them (ie, if sci.aquaria is refiled to rec.aquaria, then - get the news there) */ - case '=': return TR_BOGUS; - default: moderated = nullstr; + case 'n': + moderated = getval("NOPOSTRING"," (no posting)"); + break; + case 'm': + moderated = getval("MODSTRING", " (moderated)"); + break; + case 'x': + redirected = nullstr; + moderated = " (DISABLED)"; + break; + case '=': + len = strlen(tmpbuf); + if (tmpbuf[len-1] == '\n') + tmpbuf[len-1] = '\0'; + redirected = savestr(rindex(tmpbuf, '=') + 1); + moderated = " (REDIRECTED)"; + break; + default: + moderated = nullstr; + break; } } Index:ngdata.h @@ -30,4 +30,5 @@ EXT char *moderated; +EXT char *redirected; EXT bool ThreadedGroup; EXT long activeitems; /* number of enties in active file */ Index:nntp.c @@ -43,5 +43,5 @@ return FALSE; } - if (num) { + if (num >= 0) { long count, first, last; Index:nntpinit.c @@ -106,4 +106,8 @@ int s; struct sockaddr_in sin; +#ifdef __hpux + int socksize = 0; + int socksizelen = sizeof socksize; +#endif #ifdef NONETDB bzero((char *) &sin, sizeof(sin)); @@ -223,4 +227,19 @@ #endif /* !EXCELAN */ #endif /* !h_addr */ +#ifdef __hpux /* recommended by raj@cup.hp.com */ +#define HPSOCKSIZE 0x8000 + getsockopt(s, SOL_SOCKET, SO_SNDBUF, (caddr_t)&socksize, (caddr_t)&socksizelen); + if (socksize < HPSOCKSIZE) { + socksize = HPSOCKSIZE; + setsockopt(s, SOL_SOCKET, SO_SNDBUF, (caddr_t)&socksize, sizeof(socksize)); + } + socksize = 0; + socksizelen = sizeof(socksize); + getsockopt(s, SOL_SOCKET, SO_RCVBUF, (caddr_t)&socksize, (caddr_t)&socksizelen); + if (socksize < HPSOCKSIZE) { + socksize = HPSOCKSIZE; + setsockopt(s, SOL_SOCKET, SO_RCVBUF, (caddr_t)&socksize, sizeof(socksize)); + } +#endif return s; } Index:rcstuff.c @@ -108,5 +108,6 @@ else softptr[newng] = 0; - some_buf[--length] = '\0'; /* wipe out newline */ + if (some_buf[--length] == '\n') + some_buf[length] = '\0'; /* wipe out newline */ if (checkflag) /* no extra mallocs for -c */ rcline[newng] = some_buf; @@ -206,11 +207,13 @@ { char *s; + int len; - for (s = rcline[ngnum]; *s && *s != ':' && *s != NEGCHAR; s++) ; - if (!*s && !checkflag) { + for (s=rcline[ngnum]; *s && *s!=':' && *s!=NEGCHAR && !isspace(*s); s++) ; + len = s - rcline[ngnum]; + if ((!*s || isspace(*s)) && !checkflag) { #ifndef lint - rcline[ngnum] = saferealloc(rcline[ngnum], - (MEM_SIZE)(s - rcline[ngnum]) + 3); -#endif /* lint */ + rcline[ngnum] = saferealloc(rcline[ngnum],(MEM_SIZE)len + 3); +#endif + s = rcline[ngnum] + len; strcpy(s, ": "); } @@ -220,5 +223,5 @@ } else rcchar[ngnum] = *s; /* salt away the : or ! */ - rcnums[ngnum] = (char)(s - rcline[ngnum]) + 1; + rcnums[ngnum] = (char)len + 1; /* remember where the numbers are */ *s = '\0'; /* null terminate newsgroup name */ @@ -335,6 +338,6 @@ goto check_fuzzy_match; } - autosub = auto_subscribe(ngname); - if (!autosub) autosub = addnewbydefault; + if (mode != 'i' || !(autosub = auto_subscribe(ngname))) + autosub = addnewbydefault; if (autosub) { if (append_unsub) { @@ -925,4 +928,6 @@ finalize(1); } + get_anything(); + putchar('\n') FLUSH; } else { Index:respond.c @@ -55,5 +55,5 @@ cmd = tolower(cmd); parseheader(art); -#ifdef METAMAIL +#ifdef MIME_SUPPORT savefrom = (!mime_article && (cmd == 'w' || cmd == 'e')) #else @@ -167,5 +167,5 @@ if (*art_buf <= ' ') continue; /* Ignore empty or initially-whitespace lines */ -#ifdef METAMAIL +#ifdef MIME_SUPPORT if (mime_article) { char oldmode = mode; Index:rt-mt.h @@ -17,5 +17,9 @@ typedef char BYTE; typedef short WORD; +#ifndef __alpha typedef long LONG; +#else +typedef int LONG; +#endif #define ROOT_ARTICLE 0x0001 /* article flag definitions */ Index:rt-ov.c @@ -172,6 +172,4 @@ #endif /* !USE_XOVER */ } - if (last_buf != buf) - free(last_buf); cachemask = (ThreadedGroup? AF_THREADED : AF_CACHED); for (an = first, ap = article_ptr(an); an <= artnum; an++, ap++) { @@ -215,4 +213,6 @@ #endif setspin(SPIN_POP); + if (last_buf != buf) + free(last_buf); return success; } Index:rt-page.c @@ -429,4 +429,6 @@ maybe_eol(); #endif + if (redirected && redirected != nullstr) + printf("\t** Please start using %s **", redirected); putchar('\n') FLUSH; try_again: Index:rt-process.c @@ -45,5 +45,5 @@ article = (ARTICLE *)safemalloc(sizeof (ARTICLE)); bzero((char*)article, sizeof (ARTICLE)); - article->flags |= AF_READ|AF_MISSING|AF_FAKE|AF_TMPMEM; + article->flags |= AF_READ|AF_FAKE|AF_TMPMEM; } return article; Index:rt-select.c @@ -792,6 +792,5 @@ return DS_DISPLAY; } - sprintf(buf,"That command does not work in the set-unread selector."); - return DS_STATUS; + return DS_QUIT; case 'T': if (!ThreadedGroup) { Index:rt-util.c @@ -77,6 +77,6 @@ ** we try "Ross D Ridge", "Ross Ridge", "R D Ridge" and finally "R Ridge" ** before simply truncating the thing. We also turn "R. Douglas Ridge" -** into "Douglas Ridge" if it fits, otherwise it goes through the normal -** modification route. +** into "Douglas Ridge" and "Ross Ridge D.D.S." into "Ross Ridge" as a +** first step of the compaction, if needed. */ char * @@ -132,4 +132,7 @@ return name; } + /* If the last name is an abbreviation it's not the one we want. */ + if (*s == '.') + notlast = 1; while (!isspace(*s)) { if (s == name) { /* only one name */ @@ -338,8 +341,14 @@ int size; { - char *s; + char *s, *t; int len; - strcpy(cmd_buf, ap && ap->from? ap->from : nullstr); + for (t = cmd_buf, s = ap && ap->from? ap->from : nullstr; *s; ) { + if ((unsigned char)*s < ' ') + *t++ = ' ', s++; + else + *t++ = *s++; + } + *t = '\0'; if ((s = extract_name(cmd_buf)) != NULL) s = compress_name(s, size); Index:rthread.c @@ -141,4 +141,5 @@ sel_last_sp = 0; selected_only = FALSE; + sel_exclusive = 0; ov_close(); } @@ -257,6 +258,14 @@ if ((artp = ap) != Nullart) art = article_num(ap); - else - art = lastart+1; + else { + if (art <= last_cached) + art = last_cached+1; + else + art++; + if (art <= lastart) + artp = article_ptr(art); + else + art = lastart+1; + } return; } @@ -508,5 +517,5 @@ return FALSE; } - } while ((ap->flags & (AF_READ|AF_MISSING)) + } while ((ap->flags & AF_MISSING) || (selected_only && !(ap->flags & AF_SEL))); artp = ap; @@ -1201,6 +1210,7 @@ firstart = lastart+1; - for (sp = first_subject; sp; sp = sp->next) - sp->flags &= ~SF_VISIT; + if (mode != CS_RETAIN) + for (sp = first_subject; sp; sp = sp->next) + sp->flags &= ~SF_VISIT; for (sp = first_subject; sp; sp = sp->next) { subjdate = 0; @@ -1250,5 +1260,5 @@ } } - if (mode && !article_count && !selected_only) { + if (mode != CS_RETAIN && !article_count && !selected_only) { for (sp = first_subject; sp; sp = sp->next) sp->flags |= SF_VISIT; Index:rthread.h @@ -60,8 +60,9 @@ void sort_subjects _((void)); void count_subjects _((int)); -#define CS_NORM 0 -#define CS_RESELECT 1 -#define CS_UNSELECT 2 -#define CS_UNSEL_STORE 3 +#define CS_RETAIN 0 +#define CS_NORM 1 +#define CS_RESELECT 2 +#define CS_UNSELECT 3 +#define CS_UNSEL_STORE 4 int subjorder_date _((SUBJECT**, SUBJECT**)); Index:term.c @@ -24,4 +24,8 @@ #include "term.h" +#ifdef u3b2 +#undef TIOCGWINSZ +#endif + char ERASECH; /* rubout character */ char KILLCH; /* line delete character */ Index:trn.1 @@ -1909,4 +1909,8 @@ \*(L"%\\C\*(R" produces \*(L"rec\\.humor\*(R". .PP +Inserting \*(L"'\*(R" will single-quote the entire result and insert a +backslash before any single-quotes in the result itself: +\*(L"%'s\*(R" might produce \*(L"'I\\'m a subject'\*(R". +.PP Inserting \*(L":FMT\*(R" will format the result according to the printf-style FMT string: \*(L"%:-50.50s\*(R" left-justifies the subject into a 50