🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.emacs.gnus
Article #81480

A replacement for nntp.el

#81480
From: Felix Lee
Date: Wed, 03 Feb 1993 06:53
1135 lines
48944 bytes
Well, it took longer than I thought, and I still didn't do everything
I wanted, but I'm rather sick of elisp right now, so here it is.  It's
stable, but I won't certify it's bug-free and 100% compatible.  In
particular, I didn't try to duplicate the strange bug-compatibility
stuff in GNUS's nntp.el (like nntp-maximum-request).
--

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README chat.el chat.elc.uu nntp.el nntp.elc.uu
# Wrapped by flee@cs.psu.edu on Wed Feb  3 01:20:48 1993
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(2280 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X* Introduction
X
XThis kit contains a drop-in replacement for nntp.el in GNUS 3.14.1.
XIt will probably also work with GNUS 3.14.3.
X
XThis replacement is marginally faster at parsing nntp output in
Xgeneral, but the major improvement is it will use the nntp XOVER
Xextension, if it is available.  With XOVER, entering a newsgroup is
Xsubstantially faster: reading and parsing 600 headers takes about 2s
Xon a Sun-4/20 (but threading is still quite slow).
X
XWithout XOVER, this kit may not be worth it.  But it should be easy to
Xtry it, and easy to back out from.
X
X
X* Installing.
X
XThis kit contains:
X	README
X	chat.el
X	chat.elc.uu
X	nntp.el
X	nntp.elc.uu
X
XCopy chat.el and nntp.el to your elisp directory.  nntp.el is a direct
Xreplacement for the nntp.el that comes with GNUS.  chat.el is an
Xauxiliary module needed by nntp.el.
X
Xuudecode chat.elc.uu and nntp.elc.uu, and copy those into your elisp
Xdirectory.  You can byte-compile the files yourself, but these were
Xbyte-compiled with Jamie Zawinski's byte compiler, which is better
Xthan the one distributed with Emacs 18.  (You can get Zawinski's byte
Xcompiler from the elisp archive, which is based at
Xarchive.cis.ohio-state.edu.)
X
X
X* XOVER
X
XThere are two types of news server that support XOVER:
X
X1. INN version 1.3 supports an overview database and XOVER directly.
X
X2. C News/nntpd.  C News needs to be augmented with Geoff Collyer's
Xnov.dist.tar.Z (available from world.std.com).  nntpd needs to be
Xaugmented with the XOVER patch (available from ?), which should become
X"standard" with the next release of nntpd.
X
X
X* About Xrefs.
X
XGNUS relies on the Xref: header to mark crossposted articles
Xcorrectly.  By default, the overview database does not include Xref:
Xinformation.
X
XIf you do not have Xref: data, this nntp.el tries to adapt by grabbing
Xthe Xref: header when you retrieve an article.  This works much of the
Xtime, but isn't perfect.  In particular, kill files and catch-up
Xprobably won't mark crossposted articles correctly.
X
XA better idea is to include Xref: data in the overview database.  For
Xnov.dist, you just need to uncomment the line in mkov.c that says:
X	/* putextfld("xref", hdrp->h_xref); */
X
XI don't know what you need to do for INN.
X
X
X* Feedback.
X
XSend bugs, comments to:
X	Felix Lee <flee@cs.psu.edu>
X
X2 Feb 1993
X--
END_OF_FILE
if test 2280 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'chat.el' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'chat.el'\"
else
echo shar: Extracting \"'chat.el'\" \(7453 characters\)
sed "s/^X//" >'chat.el' <<'END_OF_FILE'
X;;;;;;;;;;;;;;;;
X;;; chat - A method for talking to asynchronous processes.
X
X;; $Id: chat.el,v 1.6 1993/02/03 02:12:02 flee Exp $
X
X(provide 'chat)
X(require 'backquote)
X
X;; Data from an asynchronous process gets appended to the process's
X;; buffer as soon as it's available.
X
X;; The data may come in pieces smaller than the units a caller wants
X;; to deal with, so here are functions that wait for conditions, like
X;; receiving a particular string, or receiving N bytes.
X
X;; The functions also keep a caller from seeing more data than it
X;; wants: each process buffer has a data mark that keeps track of how
X;; much of the buffer has actually been waited for.
X
X;; A typical use is:
X;;	(chat/with-data-until-string "\n" proc
X;;	  (buffer-substring (point-min) (1- (point-max))))
X;; which waits until we receive a line of text, and returns the line
X;; without the "\n".
X
X;; XXX It would be nice if we could provide timeouts for waiting on
X;; data, but this is really awkward to do.
X
X;; XXX There's something that's not quite right about this module; but
X;; let's run with it for a little while and see what happens.
X
X;; XXX point in the process buffer is left alone, up to the caller to
X;; modify.  Maybe it should always be set to the beginning of input?
X
X;;;;;;;;;;;;;;;;
X;;; The data mark.
X
X(defvar chat/data-marker nil
X  "A buffer's data marker.")
X(make-variable-buffer-local 'chat/data-marker)
X
X(defmacro chat/set-data-marker (location)
X  "Set the current buffer's data marker to LOCATION.  Returns the data
Xmarker."
X  (` (set-marker
X      (if (markerp chat/data-marker)
X	  chat/data-marker
X	(setq chat/data-marker (make-marker)))
X      (, location))))
X
X;;;;;;;;;;;;;;;;
X;;; Waiting for data.
X
X;; XXX Need to add some comments on efficiency.
X;; wait-for-length is linear,
X;; wait-for-string is rectangular,
X;; wait-for-regexp is quadratic or worse,
X;; wait-for-dot-crlf is linear.
X
X;; This is the error that's signalled when you try to chat with a
X;; process that's gone.
X(put 'no-process 'error-conditions '(error no-process))
X(put 'no-process 'error-message "Connection is broken")
X
X(defmacro chat/with-buffer-of (proc &rest forms)
X  "Set the current buffer to PROC's buffer, and evaluate FORMS."
X  (` (save-excursion
X       (set-buffer (process-buffer (, proc)))
X       (,@ forms))))
X(put 'chat/with-buffer-of 'lisp-indent-hook 1)
X
X;; XXX should we consider stopped processes as runnable?
X(defmacro chat/accept-from (proc)
X  (` (if (memq (process-status (, proc)) '(open run))
X	 (accept-process-output (, proc))
X       (signal 'no-process (, proc)))))
X
X(defun chat/wait-for-length (size proc)
X  "Wait until we have SIZE characters of data from PROC.  When
Xsuccessful, returns true and sets PROC's data mark to the location
Xafter SIZE.  Does not change the match data.  Signals 'no-process if
XPROC has died."
X  (chat/with-buffer-of proc
X    (while (< (point-max) (+ (point-min) size))
X      (chat/accept-from proc))
X    (chat/set-data-marker (+ (point-min) size))))
X
X(defun chat/wait-for-string (string proc)
X  "Wait until we see STRING in PROC's data.  When successful, returns
Xtrue and sets PROC's data mark to the end of the STRING match.  Also
Xsets the match data.  Signals 'no-process if PROC has died."
X  (chat/with-buffer-of proc
X    (goto-char (point-min))
X    (while (not (search-forward string nil 'eob))
X      ;; This mess is mostly because 'accept-process-output does nasty
X      ;; things to point.
X      (goto-char (prog1 (- (point) (length string))
X		   (chat/accept-from proc))))
X    (chat/set-data-marker (point))))
X
X(defun chat/wait-for-regexp (regexp proc)
X  "Wait until we see REGEXP in PROC's data.  When successful, returns
Xtrue and sets PROC's data mark to the end of the REGEXP match.  Also
Xsets the match data.  Signals 'no-process if PROC has died."
X  (chat/with-buffer-of proc
X    (save-excursion
X      (goto-char (point-min))
X      (while (not (re-search-forward regexp nil t))
X	(chat/accept-from proc)
X	;; We can't optimize the next search, because we don't know
X	;; anything about what the regexp won't match.
X	(goto-char (point-min)))
X      (chat/set-data-marker (point)))))
X
X(defun chat/wait-for-dot-crlf (proc)
X  "The same as (chat/wait-for-regexp \"^\\\\.\\r\\n\" PROC), but
Xconsiderably faster."
X  (chat/with-buffer-of proc
X    (save-excursion
X      (goto-char (point-min))
X      (if (not (looking-at ".\r?\n"))
X	  (while (not (and (search-forward "\n." nil 'eob)
X			   (looking-at "\r?\n")))
X	    (if (eobp)
X		;; This mess is mainly because 'accept-process-output
X		;; does nasty things with point.
X		(goto-char (prog1 (- (point) 2)
X			     (chat/accept-from proc))))))
X      (forward-line)
X      (chat/set-data-marker (point)))))
X
X;;;;;;;;;;;;;;;;
X;;; Processing the data.
X
X(defmacro chat/with-data-of (proc &rest forms)
X  "Set the current buffer to PROC's buffer, narrowed to the region up
Xto PROC's data mark, and evaluate FORMS.  And then the data up to the
Xdata mark is deleted.  Returns the value of FORMS.
X
XIf you discover you didn't really need all the data and want to push
Xsome back, use 'chat/set-data-marker to change the data mark.  Or
Xconsider using 'chat/with-buffer-of instead."
X  (` (chat/with-buffer-of (, proc)
X       (prog1
X	   (save-restriction
X	     (narrow-to-region (point-min) chat/data-marker)
X	     (,@ forms))
X	 (delete-region (point-min) chat/data-marker)))))
X(put 'chat/with-data-of 'lisp-indent-hook 1)
X
X(defun chat/data-of (proc)
X  "Returns a string that contains PROC's data up to its data mark, and
Xdeletes the data.  If you need to do any parsing, you probably want to
Xbe using 'chat/with-data-of instead."
X  (chat/with-data-of proc
X    (prog1 (buffer-string)
X      (delete-region (point-min) (point-max)))))
X
X(defun chat/delete-pending-data (proc)
X  "Clear out as much of PROC's pending data that we can without
Xblocking.  Returns nothing."
X  (chat/with-buffer-of proc
X    (widen)
X    (while (< (point-min) (point-max))
X      (delete-region (point-min) (point-max))
X      (accept-process-output))))
X
X;;;;;;;;;;;;;;;;
X;;; Waiting and processing.
X
X;; XXX factor the expansions of these routines for efficiency?
X
X(defmacro chat/with-data-for-length (length proc &rest forms)
X  "(LENGTH PROC FORMS ...).  Equivalent to
X	(chat/wait-for-length LENGTH PROC)
X	(chat/with-data-of PROC FORMS ...)
X"
X  (` (progn
X       (chat/wait-for-length (, length) (, proc))
X       (chat/with-data-of (, proc) (,@ forms)))))
X(put 'chat/with-data-for-length 'lisp-indent-hook 2)
X
X(defmacro chat/with-data-until-string (string proc &rest forms)
X  "(STRING PROC FORMS ...).  Equivalent to
X	(chat/wait-for-string STRING PROC)
X	(chat/with-data-of PROC FORMS ...)
X"
X  (` (progn
X       (chat/wait-for-string (, string) (, proc))
X       (chat/with-data-of (, proc) (,@ forms)))))
X(put 'chat/with-data-until-string 'lisp-indent-hook 2)
X
X(defmacro chat/with-data-until-regexp (regexp proc &rest forms)
X  "(REGEXP PROC FORMS ...).  Equivalent to
X	(chat/wait-for-regexp REGEXP PROC)
X	(chat/with-data-of PROC FORMS ...)
X"
X  (` (progn
X       (chat/wait-for-regexp (, regexp) (, proc))
X       (chat/with-data-of (, proc) (,@ forms)))))
X(put 'chat/with-data-until-regexp 'lisp-indent-hook 2)
X
X(defmacro chat/with-data-until-dot-crlf (proc &rest forms)
X  "(PROC FORMS ...).  Equivalent to
X	(chat/wait-for-dot-crlf PROC)
X	(chat/with-data-of PROC FORMS ...)
X"
X  (` (progn
X       (chat/wait-for-dot-crlf (, proc))
X       (chat/with-data-of (, proc) (,@ forms)))))
X(put 'chat/with-data-until-dot-crlf 'lisp-indent-hook 1)
END_OF_FILE
if test 7453 -ne `wc -c <'chat.el'`; then
    echo shar: \"'chat.el'\" unpacked with wrong size!
fi
# end of 'chat.el'
fi
if test -f 'chat.elc.uu' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'chat.elc.uu'\"
else
echo shar: Extracting \"'chat.elc.uu'\" \(7673 characters\)
sed "s/^X//" >'chat.elc.uu' <<'END_OF_FILE'
Xbegin 644 chat.elc
XM"BAP<F]V:61E("AQ=6]T92!C:&%T*2D*"BAR97%U:7)E("AQ=6]T92!B86-K
XM<75O=&4I*0H**&1E9G9A<B!C:&%T+V1A=&$M;6%R:V5R(&YI;" B7 I!(&)U
XM9F9E<B=S(&1A=&$@;6%R:V5R+B(I"@HH;6%K92UV87)I86)L92UB=69F97(M
XM;&]C86P@*'%U;W1E(&-H870O9&%T82UM87)K97(I*0H**&1E9FUA8W)O(&-H
XM870O<V5T+61A=&$M;6%R:V5R("AL;V-A=&EO;BD@(E-E="!T:&4@8W5R<F5N
XM="!B=69F97(G<R!D871A(&UA<FME<B!T;R!,3T-!5$E/3BX@(%)E='5R;G,@
XM=&AE(&1A=&$*;6%R:V5R+B(@*&)Y=&4M8V]D92 BP<((18<B(%ML;V-A=&EO
XM;B!S970M;6%R:V5R("AI9B H;6%R:V5R<"!C:&%T+V1A=&$M;6%R:V5R*2!C
XM:&%T+V1A=&$M;6%R:V5R("AS971Q(&-H870O9&%T82UM87)K97(@*&UA:V4M
XM;6%R:V5R*2DI72 S*2D*"BAP=70@*'%U;W1E(&YO+7!R;V-E<W,I("AQ=6]T
XM92!E<G)O<BUC;VYD:71I;VYS*2 H<75O=&4@*&5R<F]R(&YO+7!R;V-E<W,I
XM*2D*"BAP=70@*'%U;W1E(&YO+7!R;V-E<W,I("AQ=6]T92!E<G)O<BUM97-S
XM86=E*2 B0V]N;F5C=&EO;B!I<R!B<F]K96XB*0H**&1E9FUA8W)O(&-H870O
XM=VET:"UB=69F97(M;V8@*'!R;V,@)G)E<W0@9F]R;7,I(")3970@=&AE(&-U
XM<G)E;G0@8G5F9F5R('1O(%!23T,G<R!B=69F97(L(&%N9"!E=F%L=6%T92!&
XM3U)-4RXB("AB>71E+6-O9&4@(L+#Q,4(1$1$"5PBAR(@6W!R;V,@9F]R;7,@
XM87!P96YD('-A=F4M97AC=7)S:6]N('-E="UB=69F97(@<')O8V5S<RUB=69F
XM97)=(#4I*0H**'!U=" H<75O=&4@8VAA="]W:71H+6)U9F9E<BUO9BD@*'%U
XM;W1E(&QI<W M:6YD96YT+6AO;VLI(#$I"@HH9&5F;6%C<F\@8VAA="]A8V-E
XM<'0M9G)O;2 H<')O8RD@*&)Y=&4M8V]D92 BP<+#"$3$1<4(1,;'"$5&AR(@
XM6W!R;V,@:68@;65M<2!P<F]C97-S+7-T871U<R H<75O=&4@*&]P96X@<G5N
XM*2D@86-C97!T+7!R;V-E<W,M;W5T<'5T('-I9VYA;" H<75O=&4@;F\M<')O
XM8V5S<RE=(#8I*0H**&1E9G5N(&-H870O=V%I="UF;W(M;&5N9W1H("AS:7IE
XM('!R;V,I(")<"E=A:70@=6YT:6P@=V4@:&%V92!325I%(&-H87)A8W1E<G,@
XM;V8@9&%T82!F<F]M(%!23T,N("!7:&5N"G-U8V-E<W-F=6PL(')E='5R;G,@
XM=')U92!A;F0@<V5T<R!04D]#)W,@9&%T82!M87)K('1O('1H92!L;V-A=&EO
XM;@IA9G1E<B!325I%+B @1&]E<R!N;W0@8VAA;F=E('1H92!M871C:"!D871A
XM+B @4VEG;F%L<R G;F\M<')O8V5S<R!I9@I04D]#(&AA<R!D:65D+B(@*&)Y
XM=&4M8V]D92 BBL,((7&(9&4)7%Q7A20 Q @AQ3Z#' #&""&"( #'R A<(HB"
XM!@"(R<H*(8,P  J"- #+((D290E<7%PB*8<B(%MP<F]C('-I>F4@8VAA="]D
XM871A+6UA<FME<B!P<F]C97-S+6)U9F9E<B!P<F]C97-S+7-T871U<R H;W!E
XM;B!R=6XI(&%C8V5P="UP<F]C97-S+6]U='!U="!S:6=N86P@;F\M<')O8V5S
XM<R!S970M;6%R:V5R(&UA<FME<G @;6%K92UM87)K97)=(#$P*2D*"BAD969U
XM;B!C:&%T+W=A:70M9F]R+7-T<FEN9R H<W1R:6YG('!R;V,I(")<"E=A:70@
XM=6YT:6P@=V4@<V5E(%-44DE.1R!I;B!04D]#)W,@9&%T82X@(%=H96X@<W5C
XM8V5S<V9U;"P@<F5T=7)N<PIT<G5E(&%N9"!S971S(%!23T,G<R!D871A(&UA
XM<FL@=&\@=&AE(&5N9"!O9B!T:&4@4U1224Y'(&UA=&-H+B @06QS;PIS971S
XM('1H92!M871C:"!D871A+B @4VEG;F%L<R G;F\M<')O8V5S<R!I9B!04D]#
XM(&AA<R!D:65D+B(@*&)Y=&4M8V]D92 BBL0((7&(96*(Q0G"QB,_A2X 8 E'
XM6L<((<@^@R0 R0@A@B@ RLL(7"*(8HB""0"(S,T+(8,Z  N"/@#.((D38%PB
XM*8<B(%MP<F]C('-T<FEN9R!N:6P@8VAA="]D871A+6UA<FME<B!P<F]C97-S
XM+6)U9F9E<B!S96%R8V@M9F]R=V%R9"!E;V(@<')O8V5S<RUS=&%T=7,@*&]P
XM96X@<G5N*2!A8V-E<'0M<')O8V5S<RUO=71P=70@<VEG;F%L(&YO+7!R;V-E
XM<W,@<V5T+6UA<FME<B!M87)K97)P(&UA:V4M;6%R:V5R72 Q,"DI"@HH9&5F
XM=6X@8VAA="]W86ET+69O<BUR96=E>' @*')E9V5X<"!P<F]C*2 B7 I786ET
XM('5N=&EL('=E('-E92!214=%6% @:6X@4%)/0R=S(&1A=&$N("!7:&5N('-U
XM8V-E<W-F=6PL(')E='5R;G,*=')U92!A;F0@<V5T<R!04D]#)W,@9&%T82!M
XM87)K('1O('1H92!E;F0@;V8@=&AE(%)%1T584"!M871C:"X@($%L<V\*<V5T
XM<R!T:&4@;6%T8V@@9&%T82X@(%-I9VYA;',@)VYO+7!R;V-E<W,@:68@4%)/
XM0R!H87,@9&EE9"XB("AB>71E+6-O9&4@(HK%""%QB(IE8HC&"<+#(S^%+ #'
XM""'(/H,A ,D((8(E ,K+"%PBB&5BB((* (C,S0PA@S@ #((\ ,X@B11@7"(I
XM*8<B(%MP<F]C(')E9V5X<"!N:6P@="!C:&%T+V1A=&$M;6%R:V5R('!R;V-E
XM<W,M8G5F9F5R(')E+7-E87)C:"UF;W)W87)D('!R;V-E<W,M<W1A='5S("AO
XM<&5N(')U;BD@86-C97!T+7!R;V-E<W,M;W5T<'5T('-I9VYA;"!N;RUP<F]C
XM97-S('-E="UM87)K97(@;6%R:V5R<"!M86ME+6UA<FME<ET@,3 I*0H**&1E
XM9G5N(&-H870O=V%I="UF;W(M9&]T+6-R;&8@*'!R;V,I(")<"E1H92!S86UE
XM(&%S("AC:&%T+W=A:70M9F]R+7)E9V5X<"!<(EY<7%Q<+EQ<<EQ<;EPB(%!2
XM3T,I+"!B=70*8V]N<VED97)A8FQY(&9A<W1E<BXB("AB>71E+6-O9&4@(HK#
XM""%QB(IE8HC$Q2$_A3\ QL?!R".%' #$R2$_A3\ ;84[ &#*6LL((<P^@S4 
XMS0@A@CD SL\(7"*(8HB"$0"(T""(T=(*(8-.  J"4@#3((D28%PB*2F'(B!;
XM<')O8R!N:6P@8VAA="]D871A+6UA<FME<B!P<F]C97-S+6)U9F9E<B!L;V]K
XM:6YG+6%T("(N#3\*(B!S96%R8V@M9F]R=V%R9" B"BXB(&5O8B B#3\*(B R
XM('!R;V-E<W,M<W1A='5S("AO<&5N(')U;BD@86-C97!T+7!R;V-E<W,M;W5T
XM<'5T('-I9VYA;"!N;RUP<F]C97-S(&9O<G=A<F0M;&EN92!S970M;6%R:V5R
XM(&UA<FME<G @;6%K92UM87)K97)=(#$S*2D*"BAD969M86-R;R!C:&%T+W=I
XM=&@M9&%T82UO9B H<')O8R F<F5S="!F;W)M<RD@(E-E="!T:&4@8W5R<F5N
XM="!B=69F97(@=&\@4%)/0R=S(&)U9F9E<BP@;F%R<F]W960@=&\@=&AE(')E
XM9VEO;B!U< IT;R!04D]#)W,@9&%T82!M87)K+"!A;F0@979A;'5A=&4@1D]2
XM35,N("!!;F0@=&AE;B!T:&4@9&%T82!U<"!T;R!T:&4*9&%T82!M87)K(&ES
XM(&1E;&5T960N("!2971U<FYS('1H92!V86QU92!O9B!&3U)-4RX*"DEF('EO
XM=2!D:7-C;W9E<B!Y;W4@9&ED;B=T(')E86QL>2!N965D(&%L;"!T:&4@9&%T
XM82!A;F0@=V%N="!T;R!P=7-H"G-O;64@8F%C:RP@=7-E("=C:&%T+W-E="UD
XM871A+6UA<FME<B!T;R!C:&%N9V4@=&AE(&1A=&$@;6%R:RX@($]R"F-O;G-I
XM9&5R('5S:6YG("=C:&%T+W=I=&@M8G5F9F5R+6]F(&EN<W1E860N(B H8GET
XM92UC;V1E("+"",/$Q0E<(L9%18<B(%MP<F]C(&9O<FUS(&-H870O=VET:"UB
XM=69F97(M;V8@<')O9S$@87!P96YD("AS879E+7)E<W1R:6-T:6]N("AN87)R
XM;W<M=&\M<F5G:6]N("AP;VEN="UM:6XI(&-H870O9&%T82UM87)K97(I*2 H
XM9&5L971E+7)E9VEO;B H<&]I;G0M;6EN*2!C:&%T+V1A=&$M;6%R:V5R*5T@
XM-BDI"@HH<'5T("AQ=6]T92!C:&%T+W=I=&@M9&%T82UO9BD@*'%U;W1E(&QI
XM<W M:6YD96YT+6AO;VLI(#$I"@HH9&5F=6X@8VAA="]D871A+6]F("AP<F]C
XM*2 B7 I2971U<FYS(&$@<W1R:6YG('1H870@8V]N=&%I;G,@4%)/0R=S(&1A
XM=&$@=7 @=&\@:71S(&1A=&$@;6%R:RP@86YD"F1E;&5T97,@=&AE(&1A=&$N
XM("!)9B!Y;W4@;F5E9"!T;R!D;R!A;GD@<&%R<VEN9RP@>6]U('!R;V)A8FQY
XM('=A;G0@=&\*8F4@=7-I;F<@)V-H870O=VET:"UD871A+6]F(&EN<W1E860N
XM(B H8GET92UC;V1E("**P@@A<8B,PV4)7"*(Q"#%961<(H@IQ64)7"*(*8<B
XM(%MP<F]C(&-H870O9&%T82UM87)K97(@<')O8V5S<RUB=69F97(@;F%R<F]W
XM+71O+7)E9VEO;B!B=69F97(M<W1R:6YG(&1E;&5T92UR96=I;VY=(#@I*0H*
XM*&1E9G5N(&-H870O9&5L971E+7!E;F1I;F<M9&%T82 H<')O8RD@(EP*0VQE
XM87(@;W5T(&%S(&UU8V@@;V8@4%)/0R=S('!E;F1I;F<@9&%T82!T:&%T('=E
XM(&-A;B!W:71H;W5T"F)L;V-K:6YG+B @4F5T=7)N<R!N;W1H:6YG+B(@*&)Y
XM=&4M8V]D92 BBL$((7&(PB"(9617A1H PV5D7"*(Q""(@@D *8<B(%MP<F]C
XM('!R;V-E<W,M8G5F9F5R('=I9&5N(&1E;&5T92UR96=I;VX@86-C97!T+7!R
XM;V-E<W,M;W5T<'5T72 V*2D*"BAD969M86-R;R!C:&%T+W=I=&@M9&%T82UF
XM;W(M;&5N9W1H("AL96YG=&@@<')O8R F<F5S="!F;W)M<RD@(BA,14Y'5$@@
XM4%)/0R!&3U)-4R N+BXI+B @17%U:79A;&5N="!T;PH)*&-H870O=V%I="UF
XM;W(M;&5N9W1H($Q%3D=42"!04D]#*0H)*&-H870O=VET:"UD871A+6]F(%!2
XM3T,@1D]235,@+BXN*0HB("AB>71E+6-O9&4@(L/$" E%Q<8)1 I<(D6'(B!;
XM;&5N9W1H('!R;V,@9F]R;7,@<')O9VX@8VAA="]W86ET+69O<BUL96YG=&@@
XM87!P96YD(&-H870O=VET:"UD871A+6]F72 U*2D*"BAP=70@*'%U;W1E(&-H
XM870O=VET:"UD871A+69O<BUL96YG=&@I("AQ=6]T92!L:7-P+6EN9&5N="UH
XM;V]K*2 R*0H**&1E9FUA8W)O(&-H870O=VET:"UD871A+75N=&EL+7-T<FEN
XM9R H<W1R:6YG('!R;V,@)G)E<W0@9F]R;7,I("(H4U1224Y'(%!23T,@1D]2
XM35,@+BXN*2X@($5Q=6EV86QE;G0@=&\*"2AC:&%T+W=A:70M9F]R+7-T<FEN
XM9R!35%))3D<@4%)/0RD*"2AC:&%T+W=I=&@M9&%T82UO9B!04D]#($9/4DU3
XM("XN+BD*(B H8GET92UC;V1E("+#Q @)1<7&"40*7")%AR(@6W-T<FEN9R!P
XM<F]C(&9O<FUS('!R;V=N(&-H870O=V%I="UF;W(M<W1R:6YG(&%P<&5N9"!C
XM:&%T+W=I=&@M9&%T82UO9ET@-2DI"@HH<'5T("AQ=6]T92!C:&%T+W=I=&@M
XM9&%T82UU;G1I;"US=')I;F<I("AQ=6]T92!L:7-P+6EN9&5N="UH;V]K*2 R
XM*0H**&1E9FUA8W)O(&-H870O=VET:"UD871A+75N=&EL+7)E9V5X<" H<F5G
XM97AP('!R;V,@)G)E<W0@9F]R;7,I("(H4D5'15A0(%!23T,@1D]235,@+BXN
XM*2X@($5Q=6EV86QE;G0@=&\*"2AC:&%T+W=A:70M9F]R+7)E9V5X<"!214=%
XM6% @4%)/0RD*"2AC:&%T+W=I=&@M9&%T82UO9B!04D]#($9/4DU3("XN+BD*
XM(B H8GET92UC;V1E("+#Q @)1<7&"40*7")%AR(@6W)E9V5X<"!P<F]C(&9O
XM<FUS('!R;V=N(&-H870O=V%I="UF;W(M<F5G97AP(&%P<&5N9"!C:&%T+W=I
XM=&@M9&%T82UO9ET@-2DI"@HH<'5T("AQ=6]T92!C:&%T+W=I=&@M9&%T82UU
XM;G1I;"UR96=E>' I("AQ=6]T92!L:7-P+6EN9&5N="UH;V]K*2 R*0H**&1E
XM9FUA8W)O(&-H870O=VET:"UD871A+75N=&EL+61O="UC<FQF("AP<F]C("9R
XM97-T(&9O<FUS*2 B*%!23T,@1D]235,@+BXN*2X@($5Q=6EV86QE;G0@=&\*
XM"2AC:&%T+W=A:70M9F]R+61O="UC<FQF(%!23T,I"@DH8VAA="]W:71H+61A
XM=&$M;V8@4%)/0R!&3U)-4R N+BXI"B(@*&)Y=&4M8V]D92 BPL,(1,3%"$0)
XM7")%AR(@6W!R;V,@9F]R;7,@<')O9VX@8VAA="]W86ET+69O<BUD;W0M8W)L
XM9B!A<'!E;F0@8VAA="]W:71H+61A=&$M;V9=(#4I*0H**'!U=" H<75O=&4@
XM8VAA="]W:71H+61A=&$M=6YT:6PM9&]T+6-R;&8I("AQ=6]T92!L:7-P+6EN
X.9&5N="UH;V]K*2 Q*0HM
X 
Xend
END_OF_FILE
if test 7673 -ne `wc -c <'chat.elc.uu'`; then
    echo shar: \"'chat.elc.uu'\" unpacked with wrong size!
fi
# end of 'chat.elc.uu'
fi
if test -f 'nntp.el' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'nntp.el'\"
else
echo shar: Extracting \"'nntp.el'\" \(14604 characters\)
sed "s/^X//" >'nntp.el' <<'END_OF_FILE'
X;;;;;;;;;;;;;;;;
X;;; An NNTP module for GNUS.
X
X;; $Id: nntp.el,v 1.9 1993/02/03 05:53:57 flee Exp $
X(defvar nntp/rcs-revision "$Revision: 1.9 $")
X
X(provide 'nntp)
X(require 'backquote)
X(require 'chat)
X(or (fboundp 'open-network-stream) (require 'tcp))
X
X(or (fboundp 'last)
X    (defun last (x)
X      "Returns the last link in the list LIST."
X      (while (cdr x)
X	(setq x (cdr x)))
X      x))
X
X(defvar nntp/default-nntp-port "nntp"
X  "The default tcp port to use for nntp connections.")
X
X;;;;;;;;;;;;;;;;
X;;; NNTP state.
X
X;; Right now, we're assuming we only talk to one NNTP server at a
X;; time.  It might be nice to do multiple NNTP connections, but
X;; there's no point in doing this from the bottom up.
X
X;; (To handle multiple connections, you need to create connection
X;; handles that you pass around.  Ideally, nnspool et al would be
X;; just different types of connection handles.)
X
X(defvar nntp/connection nil
X  "The current NNTP connection.")
X
X(defvar nntp/error-message nil
X  "The error message from the last NNTP command.  'nil if no error.")
X
X(defvar nntp/can-xover t
X  "Does this server understand the XOVER command?")
X
X;;;;;;;;;;;;;;;;
X;;; The GNUS interface.
X
X;; These are the symbols that GNUS knows about and expects.
X
X;; The interaction between GNUS and nntp.el (or nnspool.el) is a
X;; little messy and not particularly well defined.
X
X(defvar nntp-version
X  (concat "flee/nntp " (substring nntp/rcs-revision 10)))
X
X(defvar nntp-server-buffer nil
X  "Buffer that GNUS looks at when it wants data.")
X
X(defun nntp-open-server (host service)
X  "Start a connection to the given HOST and SERVICE.  Returns true
Xif successful."
X  ;; XXX already open?
X  (or service (setq service nntp/default-nntp-port))
X  (setq nntp/error-message nil)
X  (setq nntp/can-xover t)
X  (setq nntp-server-buffer (generate-new-buffer "*nntp*"))
X  (buffer-flush-undo nntp-server-buffer)
X  (setq nntp/connection
X	(open-network-stream "nntp" nntp-server-buffer host service))
X  (set-process-sentinel nntp/connection 'nntp/sentinel)
X  (process-kill-without-query nntp/connection)
X  (let ( (code (nntp/response)) )
X    (or (eq code 200) (eq code 201))))
X
X(defun nntp-server-opened ()
X  "Are we currently connected?"
X  (and nntp/connection
X       (memq (process-status nntp/connection) '(run open))))
X;; XXX should we add stopped to this list?
X
X(defun nntp-close-server ()
X  "Terminate the connection.  Returns nothing."
X  (let ( (proc nntp/connection)
X	 (buffer nntp-server-buffer) )
X    (setq nntp/connection nil)
X    (setq nntp-server-buffer nil)
X    (and proc (delete-process proc))
X    (and buffer (kill-buffer buffer))))
X
X(defun nntp-status-message ()
X  "Returns the error message from the last NNTP request."
X  (or nntp/error-message "okay"))
X
X(defun nntp-request-list ()
X  "Retrieve the list of newsgroups into 'nntp-server-buffer.
XReturns true if successful."
X  (nntp/command "LIST")
X  (if (eq (nntp/response) 215)
X      ;; We don't do any text format conversion here.  It's wasted
X      ;; effort, since the text needs to be parsed by GNUS anyway.
X      (nntp/wait-for-text)))
X
X(defun nntp-request-group (group)
X  "Select group GROUP.  Returns true if successful."
X  (nntp/command "GROUP" group)
X  (eq (nntp/response) 211))
X
X(defun nntp-request-article (id)
X  "Retrieve article ID (either a number or a message-id) into
X'nntp-server-buffer.  Returns true if successful."
X  (nntp/command "ARTICLE" id)
X  (if (eq (nntp/response) 220)
X      (nntp/get-text)))
X
X(defun nntp-request-post ()
X  "Modify and post the current buffer.  Returns true if successful."
X  ;; The trick here is we want to make sure the conversation is in a
X  ;; sane state even if we're interrupted in middle of transmission.
X  ;; Right now, we just prematurely terminate the posting.  While this
X  ;; isn't ideal, it's better than continually adding junk to the end.
X  ;; The problem is NNTP doesn't let you abort a posting.
X  ;; XXX A better approach is to open a new connection for posting,
X  ;; but this is going to be slower, unless you anticipate the user by
X  ;; opening the connection early.
X  (nntp/command "POST")
X  (if (eq (nntp/response) 340)
X      (let ( (finished nil) )
X	(unwind-protect
X	    (progn
X	      (nntp/unix-to-smtp-text)
X	      (process-send-region nntp/connection (point-min) (point-max))
X	      (setq finished t)
X	      (eq (nntp/response) 240))
X	  (or finished
X	      (process-send-string nntp/connection "\r\n.\r\n")
X	      nil)))))
X
X(defun nntp-retrieve-headers (sequence)
X  "Returns the header data for SEQUENCE in the current group.
XSEQUENCE is a sorted list of article numbers.
XXXX describe the return value."
X  (and sequence
X       (let ( (result nil) )
X	 (message "retrieving...")
X	 (if nntp/can-xover
X	     (setq result (nntp/try-xover sequence)))
X	 (if (not nntp/can-xover)
X	     (setq result (nntp/headers sequence)))
X	 (message "retrieving...done")
X	 result)))
X
X;;;;;;;;;;;;;;;;
X;;; Talking to the NNTP server.
X
X(defun nntp/sentinel (proc delta)
X  (or (nntp-server-opened)
X      (error "NNTP connection closed.")))
X
X(defun nntp/clear ()
X  ;; XXX This resynchronization is imperfect, but is probably good
X  ;; enough for normal use.
X  (chat/delete-pending-data nntp/connection))
X
X(defun nntp/command (&rest strings)
X  "Start a new NNTP command."
X  (nntp/clear)
X  (process-send-string
X   nntp/connection
X   (concat (mapconcat 'identity strings " ") "\r\n")))
X
X;;;;;;;;;;;;;;;;
X;;; Reading from the NNTP server.
X
X(defun nntp/response ()
X  "Wait for an NNTP response and return the response code.  Also sets
X'nntp/error-message."
X  ;; XXX Emacs 18.xx has a bug that turns undo back on after a gc, so
X  ;; we continually flush undo here.
X  (buffer-flush-undo nntp-server-buffer)
X  (chat/with-data-until-string "\n" nntp/connection
X    (let ( (code (string-to-int (buffer-substring (point-min)
X						  (+ (point-min) 3)))) )
X      ;; Codes 400 and up are error conditions.
X      (setq nntp/error-message
X	    (and (<= 400 code)
X		 (buffer-substring (+ (point-min) 4) (- (point-max) 2))))
X      code)))
X
X(defun nntp/wait-for-text ()
X  "Wait for an NNTP text response.  Returns true."
X  (chat/wait-for-dot-crlf nntp/connection))
X
X(defun nntp/get-text ()
X  "Wait for an NNTP text response and convert it to Unix text format.
XReturns true."
X  (nntp/wait-for-text)
X  (save-excursion
X    (set-buffer nntp-server-buffer)
X    (nntp/smtp-to-unix-text))
X  t)
X
X;;;;;;;;;;;;;;;;
X;;; Handling the funny dot-CRLF text format used by SMTP/NNTP.
X
X(defun nntp/smtp-to-unix-text ()
X  "Convert the current buffer from SMTP text format to Unix text
Xformat.  Modifies point.  Returns nothing."
X  (goto-char (point-min))
X  (while (not (eobp))
X    (if (eq (following-char) ?.)
X	(delete-char 1))
X    (end-of-line)
X    (if (eq (preceding-char) ?\r)
X	(delete-char -1))
X    (forward-char))
X  ;; Delete the last line, which had the dot-crlf terminator.
X  (backward-char)
X  (if (eq (preceding-char) ?\n)
X      (delete-char 1))
X  )
X
X(defun nntp/unix-to-smtp-text ()
X  "Convert the current buffer form Unix text format to SMTP text
Xformat.  Modifies point.  Returns nothing."
X  (goto-char (point-min))
X  (while (not (eobp))
X    (if (eq (following-char) ?.)
X	(insert ?.))
X    (end-of-line)
X    (insert ?\r)
X    (forward-line))
X  ;; Add the terminator, but first insert a CRLF if necessary.
X  (or (bobp)
X      (eq (preceding-char) ?\n)
X      (insert "\r\n"))
X  (insert ".\r\n"))
X
X;;;;;;;;;;;;;;;;
X;;; Fetch headers using XOVER.
X
X;; XXX We could probably try splitting a sequence into segments and
X;; sending multiple XOVER commands, one for each segment.  However,
X;; this is a little more expensive for the news server to process, and
X;; mostly just reduces network traffic.  There isn't much difference
X;; in response, unless you're in the habit of leaving 100+ article
X;; gaps.  A couple hundred extra overview lines are unnoticeable on a
X;; Sun SLC.
X
X;; XXX In general, maybe we should have a gap threshhold: if a gap is
X;; larger than N, split it into two XOVER requests, but the actual
X;; tradeoffs are more complex than that.  This is really a flaw in
X;; XOVER; you should be able to give XOVER a monotonically increasing
X;; sequence of ranges, which is something that can be processed
X;; efficiently.
X
X;; XXX There's an unhappy synchronization problem here with C News.
X;; The bounds in the active file are updated before the overview data
X;; is updated, which may not happen until minutes later.  If you read
X;; the active file and enter a newsgroup soon after it receives new
X;; articles, then the overview fetch will leave out the new articles.
X;; GNUS will wrongly conclude that the articles don't exist, mark them
X;; as read, and you'll never see them.
X
X(defun nntp/try-xover (sequence)
X  "Try using the XOVER command to retrieve headers."
X  (let ( (lo (car sequence))
X	 (hi (car (last sequence))) )
X    (nntp/command "XOVER" (concat (int-to-string lo) "-" (int-to-string hi)))
X    (if (eq (nntp/response) 224)
X	(chat/with-data-until-dot-crlf nntp/connection
X	  (nov/parse sequence))
X      (setq nntp/can-xover nil)
X      nil)))
X
X;;;;;;;;;;;;;;;;
X;;; News overview parsing.
X
X;; XXX This section isn't really nntp-specific.  It probably could be
X;; a separate module by itself.
X
X;; Small changes to this code can have large impact on performance.
X
X;; You'd think that using skip-chars-forward would be faster than
X;; search-forward, but for some reason it ends up marginally slower.
X;; I suspect it's because the setup overhead for both is about the
X;; same, but the inner loop for search-forward is much more carefully
X;; coded.
X
X(defmacro nov/skip-field ()
X  '(search-forward "\t" eol 'end))
X
X(defmacro nov/field ()
X  '(buffer-substring
X    (point)
X    (progn (nov/skip-field) (1- (point)))))
X
X(defmacro nov/read-integer ()
X   "Read an integer from the current point at the buffer."
X   '(string-to-int
X     (buffer-substring (point) (progn (skip-chars-forward "0-9") (point)))))
X
X(defun nov/parse (sequence)
X  "Parse the news overview data in the current buffer, and return a
Xlist of headers that match SEQUENCE (see 'nntp-retrieve-headers)."
X  (let ( (number nil)
X	 (header nil)
X	 (headers nil)
X	 (eol nil) )
X    (goto-char (point-min))
X    (while (and sequence (not (eobp)))
X      (setq number (nov/read-integer))
X      (while (and sequence (< (car sequence) number))
X	 (setq sequence (cdr sequence)))
X      (if (and sequence (eq number (car sequence)))
X	  (progn
X	    (setq sequence (cdr sequence))
X	    (save-excursion
X	      (end-of-line)
X	      (setq eol (point)))
X	    ;; header: [num subject from xref lines date id refs]
X	    ;; overview: [num subject from date id refs lines chars misc]
X	    (setq header (make-vector 8 nil))
X	    (aset header 0 number)
X	    (forward-char)	; move past the "\t"
X	    (aset header 1 (nov/field))
X	    (aset header 2 (nov/field))
X	    (aset header 5 (nov/field))
X	    (aset header 6 (nov/field))
X	    (aset header 7 (nov/field))
X	    (nov/skip-field)
X	    (aset header 4 (string-to-int (nov/field)))
X	    (backward-char)
X	    (if (search-forward "\txref: " eol t)
X		(aset header 3 (nov/field)))
X	    (setq headers (cons header headers))
X	    ))
X      (forward-line)
X      )
X    (setq headers (nreverse headers))
X    headers))
X
X;;;;;;;;;;;;;;;;
X;;; A workaround for missing Xrefs in the overview data.
X
X(defun nntp/add-to-hook (hook-name value)
X  (let ((hook nil))
X    (if (boundp hook-name)
X	(setq hook (symbol-value hook-name)))
X    (if (or (subrp hook)
X	    (and hook (symbolp hook))
X	    (and (listp hook) (eq (car hook) 'lambda)))
X	(setq hook (list hook)))
X    (or (memq value hook)
X	(setq hook (cons value hook)))
X    (set hook-name hook)))
X
X(nntp/add-to-hook
X 'gnus-Article-prepare-hook
X 'nntp/article-get-xrefs)
X
X(defvar gnus-current-headers nil)	; from gnus.el
X
X(defun nntp/article-get-xrefs ()
X  "Fill in the Xref value in 'gnus-current-headers, if necessary.
XThis is meant to be called in 'gnus-Article-prepare-hook."
X  (or (aref gnus-current-headers 3)
X      (let ( (case-fold-search nil) )
X	(goto-char (point-min))
X	(search-forward "\n\n" nil 'end)
X	(save-restriction
X	  (narrow-to-region (point-min) (point))
X	  (goto-char (point-min))
X	  (if (or (and (eq (downcase (following-char)) ?x)
X		       (looking-at "Xref:"))
X		  (search-forward "\nXref:"))
X	      (progn
X		(goto-char (match-end 0))
X		(forward-char)
X		(aset gnus-current-headers 3
X		      (buffer-substring
X		       (point) (progn (end-of-line) (point))))
X		))))))
X
X;;;;;;;;;;;;;;;;
X;;; Fetch headers using HEAD.
X
X(defun nntp/headers (sequence)
X  (nntp/clear)
X  (message "request...")
X  (nntp/send-head-requests sequence)
X  (message "parsing...")
X  (nntp/parse-headers sequence))
X
X(defun nntp/send-head-requests (sequence)
X  (while sequence
X    (accept-process-output)
X    (process-send-string
X     nntp/connection
X     (concat "HEAD " (car sequence) "\r\n"))
X    (setq sequence (cdr sequence))
X    ))
X
X(defun nntp/parse-headers (sequence)
X  (let ( (headers nil)
X	 (code nil)
X	 (number nil) )
X    (while sequence
X      (chat/with-data-until-string "\n" nntp/connection
X	(setq code (string-to-int (buffer-substring (point-min)
X						    (+ (point-min) 4)))))
X      (if (eq code 221)
X	  (chat/with-data-until-dot-crlf nntp/connection
X	    (setq headers (cons (nntp/parse-header (car sequence)) headers)))
X	(forward-line))
X      (setq sequence (cdr sequence)))
X    (nreverse headers)))
X
X(defun nntp/header-value ()
X  (goto-char (match-end 0))
X  (skip-chars-forward "\t ")
X  (buffer-substring
X   (point)
X   (progn
X     (while
X	 (progn
X	   (end-of-line)
X	   (if (eq (preceding-char) ?\r)
X	       (delete-char -1))
X	   (forward-char)
X	   (memq (following-char) '(?\t ? )))
X       (delete-char -1)
X       (delete-char 1)
X       (insert ? ))
X     (1- (point))))
X  )
X
X(defun nntp/parse-header (number)
X  (let ( (header (make-vector 8 nil))
X	 (case-fold-search t)
X	 (fields nil) )
X    (aset header 0 number)
X    (aset header 4 0)
X    (while (not (eobp))
X      ;; header: [num subject from xref lines date id refs]
X      (if (not (looking-at "subject:\\|from:\\|xref:\\|lines:\\|date:\\|message-id:\\|references:"))
X	  (forward-line)
X	(cond
X	 ((eq (downcase (following-char)) ?s)
X	  (aset header 1 (nntp/header-value)))
X	 ((eq (downcase (following-char)) ?f)
X	  (aset header 2 (nntp/header-value)))
X	 ((eq (downcase (following-char)) ?x)
X	  (aset header 3 (nntp/header-value)))
X	 ((eq (downcase (following-char)) ?l)
X	  (aset header 4 (string-to-int (nntp/header-value))))
X	 ((eq (downcase (following-char)) ?d)
X	  (aset header 5 (nntp/header-value)))
X	 ((eq (downcase (following-char)) ?m)
X	  (aset header 6 (nntp/header-value)))
X	 ((eq (downcase (following-char)) ?r)
X	  (aset header 7 (nntp/header-value)))
X	 ))
X      )
X    header))
END_OF_FILE
if test 14604 -ne `wc -c <'nntp.el'`; then
    echo shar: \"'nntp.el'\" unpacked with wrong size!
fi
# end of 'nntp.el'
fi
if test -f 'nntp.elc.uu' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'nntp.elc.uu'\"
else
echo shar: Extracting \"'nntp.elc.uu'\" \(11533 characters\)
sed "s/^X//" >'nntp.elc.uu' <<'END_OF_FILE'
Xbegin 644 nntp.elc
XM"BAD969V87(@;FYT<"]R8W,M<F5V:7-I;VX@(B12979I<VEO;CH@,2XY("0B
XM*0H**'!R;W9I9&4@*'%U;W1E(&YN=' I*0H**')E<75I<F4@*'%U;W1E(&)A
XM8VMQ=6]T92DI"@HH<F5Q=6ER92 H<75O=&4@8VAA="DI"@HH;W(@*&9B;W5N
XM9' @*'%U;W1E(&]P96XM;F5T=V]R:RUS=')E86TI*2 H<F5Q=6ER92 H<75O
XM=&4@=&-P*2DI"@HH;W(@*&9B;W5N9' @*'%U;W1E(&QA<W0I*2 H9&5F=6X@
XM;&%S=" H>"D@(E)E='5R;G,@=&AE(&QA<W0@;&EN:R!I;B!T:&4@;&ES="!,
XM25-4+B(@*'=H:6QE("AC9'(@>"D@*'-E='$@>" H8V1R('@I*2D@>"DI"@HH
XM9&5F=F%R(&YN=' O9&5F875L="UN;G1P+7!O<G0@(FYN=' B(")<"E1H92!D
XM969A=6QT('1C<"!P;W)T('1O('5S92!F;W(@;FYT<"!C;VYN96-T:6]N<RXB
XM*0H**&1E9G9A<B!N;G1P+V-O;FYE8W1I;VX@;FEL(")<"E1H92!C=7)R96YT
XM($Y.5% @8V]N;F5C=&EO;BXB*0H**&1E9G9A<B!N;G1P+V5R<F]R+6UE<W-A
XM9V4@;FEL(")<"E1H92!E<G)O<B!M97-S86=E(&9R;VT@=&AE(&QA<W0@3DY4
XM4"!C;VUM86YD+B @)VYI;"!I9B!N;R!E<G)O<BXB*0H**&1E9G9A<B!N;G1P
XM+V-A;BUX;W9E<B!T(")<"D1O97,@=&AI<R!S97)V97(@=6YD97)S=&%N9"!T
XM:&4@6$]615(@8V]M;6%N9#\B*0H**&1E9G9A<B!N;G1P+79E<G-I;VX@*&-O
XM;F-A=" B9FQE92]N;G1P("(@*'-U8G-T<FEN9R!N;G1P+W)C<RUR979I<VEO
XM;B Q,"DI*0H**&1E9G9A<B!N;G1P+7-E<G9E<BUB=69F97(@;FEL(")<"D)U
XM9F9E<B!T:&%T($=.55,@;&]O:W,@870@=VAE;B!I="!W86YT<R!D871A+B(I
XM"@HH9&5F=6X@;FYT<"UO<&5N+7-E<G9E<B H:&]S="!S97)V:6-E*2 B7 I3
XM=&%R="!A(&-O;FYE8W1I;VX@=&\@=&AE(&=I=F5N($A/4U0@86YD(%-%4E9)
XM0T4N("!2971U<FYS('1R=64*:68@<W5C8V5S<V9U;"XB("AB>71E+6-O9&4@
XM(@B&!P )B1"(PXD2B,6)%(C*RR&)%@:(S X&(8C-S@X&#@@()(D6!XC/#@?0
XM7"*(T0X'(8C2(!X)#@G3/89"  X)U#TIAR(@6W-E<G9I8V4@;FYT<"]D969A
XM=6QT+6YN=' M<&]R="!N;G1P+V5R<F]R+6UE<W-A9V4@;FEL(&YN=' O8V%N
XM+7AO=F5R('0@;FYT<"US97)V97(M8G5F9F5R(&YN=' O8V]N;F5C=&EO;B!H
XM;W-T(&-O9&4@9V5N97)A=&4M;F5W+6)U9F9E<B B*FYN=' J(B!B=69F97(M
XM9FQU<V@M=6YD;R!O<&5N+6YE='=O<FLM<W1R96%M(")N;G1P(B!S970M<')O
XM8V5S<RUS96YT:6YE;"!N;G1P+W-E;G1I;F5L('!R;V-E<W,M:VEL;"UW:71H
XM;W5T+7%U97)Y(&YN=' O<F5S<&]N<V4@,C P(#(P,5T@."DI"@HH9&5F=6X@
XM;FYT<"US97)V97(M;W!E;F5D(&YI;" B7 I!<F4@=V4@8W5R<F5N=&QY(&-O
XM;FYE8W1E9#\B("AB>71E+6-O9&4@(@B%"0#!""'"/H<B(%MN;G1P+V-O;FYE
XM8W1I;VX@<')O8V5S<RUS=&%T=7,@*')U;B!O<&5N*5T@,RDI"@HH9&5F=6X@
XM;FYT<"UC;&]S92US97)V97(@;FEL(")<"E1E<FUI;F%T92!T:&4@8V]N;F5C
XM=&EO;BX@(%)E='5R;G,@;F]T:&EN9RXB("AB>71E+6-O9&4@(@D+&AC$B1&(
XMQ(D3B B%$P#%""&("H4; ,8*(2J'(B!;<')O8R!N;G1P+V-O;FYE8W1I;VX@
XM8G5F9F5R(&YN=' M<V5R=F5R+6)U9F9E<B!N:6P@9&5L971E+7!R;V-E<W,@
XM:VEL;"UB=69F97)=(#,I*0H**&1E9G5N(&YN=' M<W1A='5S+6UE<W-A9V4@
XM;FEL(")<"E)E='5R;G,@=&AE(&5R<F]R(&UE<W-A9V4@9G)O;2!T:&4@;&%S
XM="!.3E10(')E<75E<W0N(B H8GET92UC;V1E("((A@4 P8<B(%MN;G1P+V5R
XM<F]R+6UE<W-A9V4@(F]K87DB72 Q*2D*"BAD969U;B!N;G1P+7)E<75E<W0M
XM;&ES="!N:6P@(EP*4F5T<FEE=F4@=&AE(&QI<W0@;V8@;F5W<V=R;W5P<R!I
XM;G1O("=N;G1P+7-E<G9E<BUB=69F97(N"E)E='5R;G,@=')U92!I9B!S=6-C
XM97-S9G5L+B(@*&)Y=&4M8V]D92 BP,$AB,(@PSV%#0#$((<B(%MN;G1P+V-O
XM;6UA;F0@(DQ)4U0B(&YN=' O<F5S<&]N<V4@,C$U(&YN=' O=V%I="UF;W(M
XM=&5X=%T@-"DI"@HH9&5F=6X@;FYT<"UR97%U97-T+6=R;W5P("AG<F]U<"D@
XM(EP*4V5L96-T(&=R;W5P($=23U50+B @4F5T=7)N<R!T<G5E(&EF('-U8V-E
XM<W-F=6PN(B H8GET92UC;V1E("+!P@A<(HC#(,0]AR(@6V=R;W5P(&YN=' O
XM8V]M;6%N9" B1U)/55 B(&YN=' O<F5S<&]N<V4@,C$Q72 T*2D*"BAD969U
XM;B!N;G1P+7)E<75E<W0M87)T:6-L92 H:60I(")<"E)E=')I979E(&%R=&EC
XM;&4@240@*&5I=&AE<B!A(&YU;6)E<B!O<B!A(&UE<W-A9V4M:60I(&EN=&\*
XM)VYN=' M<V5R=F5R+6)U9F9E<BX@(%)E='5R;G,@=')U92!I9B!S=6-C97-S
XM9G5L+B(@*&)Y=&4M8V]D92 BP<((7"*(PR#$/84. ,4@AR(@6VED(&YN=' O
XM8V]M;6%N9" B05)424-,12(@;FYT<"]R97-P;VYS92 R,C @;FYT<"]G970M
XM=&5X=%T@-"DI"@HH9&5F=6X@;FYT<"UR97%U97-T+7!O<W0@;FEL(")<"DUO
XM9&EF>2!A;F0@<&]S="!T:&4@8W5R<F5N="!B=69F97(N("!2971U<FYS('1R
XM=64@:68@<W5C8V5S<V9U;"XB("AB>71E+6-O9&4@(L3%(8C&(,<]A5PB ,$8
XMR([)((C*"F5D(XC#B1"(QB#+/2DIAR(@6V9I;FES:&5D(&YI;"!N;G1P+V-O
XM;FYE8W1I;VX@="!N;G1P+V-O;6UA;F0@(E!/4U0B(&YN=' O<F5S<&]N<V4@
XM,S0P("@H8GET92UC;V1E("((A@P PPG$7"*&# #"AR(@6V9I;FES:&5D(&YN
XM=' O8V]N;F5C=&EO;B!N:6P@<')O8V5S<RUS96YD+7-T<FEN9R B#0HN#0HB
XM72 S*2D@;FYT<"]U;FEX+71O+7-M=' M=&5X="!P<F]C97-S+7-E;F0M<F5G
XM:6]N(#(T,%T@-RDI"@HH9&5F=6X@;FYT<"UR971R:65V92UH96%D97)S("AS
XM97%U96YC92D@(EP*4F5T=7)N<R!T:&4@:&5A9&5R(&1A=&$@9F]R(%-%455%
XM3D-%(&EN('1H92!C=7)R96YT(&=R;W5P+@I315%514Y#12!I<R!A('-O<G1E
XM9"!L:7-T(&]F(&%R=&EC;&4@;G5M8F5R<RX*6%A8(&1E<V-R:6)E('1H92!R
XM971U<FX@=F%L=64N(B H8GET92UC;V1E("((A24 PAG$Q2&("X43 ,8((8D1
XMB L_A1X QP@AB1&(Q,@AB DIAR(@6W-E<75E;F-E(')E<W5L="!N:6P@;FYT
XM<"]C86XM>&]V97(@;65S<V%G92 B<F5T<FEE=FEN9RXN+B(@;FYT<"]T<GDM
XM>&]V97(@;FYT<"]H96%D97)S(")R971R:65V:6YG+BXN9&]N92)=(#4I*0H*
XM*&1E9G5N(&YN=' O<V5N=&EN96P@*'!R;V,@9&5L=&$I("AB>71E+6-O9&4@
XM(L @A@@ P<(AAR(@6VYN=' M<V5R=F5R+6]P96YE9"!E<G)O<B B3DY44"!C
XM;VYN96-T:6]N(&-L;W-E9"XB72 S*2D*"BAD969U;B!N;G1P+V-L96%R(&YI
XM;" H8GET92UC;V1E("+!""&'(B!;;FYT<"]C;VYN96-T:6]N(&-H870O9&5L
XM971E+7!E;F1I;F<M9&%T85T@,BDI"@HH9&5F=6X@;FYT<"]C;VUM86YD("@F
XM<F5S="!S=')I;F=S*2 B7 I3=&%R="!A(&YE=R!.3E10(&-O;6UA;F0N(B H
XM8GET92UC;V1E("+"((C#",3%"<8CQU!<(H<B(%MN;G1P+V-O;FYE8W1I;VX@
XM<W1R:6YG<R!N;G1P+V-L96%R('!R;V-E<W,M<V5N9"US=')I;F<@;6%P8V]N
XM8V%T(&ED96YT:71Y("(@(B B#0HB72 W*2D*"BAD969U;B!N;G1P+W)E<W!O
XM;G-E(&YI;" B7 I786ET(&9O<B!A;B!.3E10(')E<W!O;G-E(&%N9"!R971U
XM<FX@=&AE(')E<W!O;G-E(&-O9&4N("!!;'-O('-E=',*)VYN=' O97)R;W(M
XM;65S<V%G92XB("AB>71E+6-O9&4@(L4((8C&QPE<(HB*R DA<8B,R64*7"*(
XMRLME9<Q<7%PB(1O-"UB%+ #+9<Y<7&3/6EPBB12("RDIT&4*7"*(*8<B(%MN
XM;G1P+7-E<G9E<BUB=69F97(@;FYT<"]C;VYN96-T:6]N(&-H870O9&%T82UM
XM87)K97(@8V]D92!N;G1P+V5R<F]R+6UE<W-A9V4@8G5F9F5R+69L=7-H+75N
XM9&\@8VAA="]W86ET+69O<BUS=')I;F<@(@HB('!R;V-E<W,M8G5F9F5R(&YA
XM<G)O=RUT;RUR96=I;VX@<W1R:6YG+71O+6EN="!B=69F97(M<W5B<W1R:6YG
XM(#,@-# P(#0@,B!D96QE=&4M<F5G:6]N72 Q,2DI"@HH9&5F=6X@;FYT<"]W
XM86ET+69O<BUT97AT(&YI;" B7 I786ET(&9O<B!A;B!.3E10('1E>'0@<F5S
XM<&]N<V4N("!2971U<FYS('1R=64N(B H8GET92UC;V1E("+!""&'(B!;;FYT
XM<"]C;VYN96-T:6]N(&-H870O=V%I="UF;W(M9&]T+6-R;&9=(#(I*0H**&1E
XM9G5N(&YN=' O9V5T+71E>'0@;FEL(")<"E=A:70@9F]R(&%N($Y.5% @=&5X
XM="!R97-P;VYS92!A;F0@8V]N=F5R="!I="!T;R!5;FEX('1E>'0@9F]R;6%T
XM+@I2971U<FYS('1R=64N(B H8GET92UC;V1E("+"((B*"'&(PR IB,&'(B!;
XM;FYT<"US97)V97(M8G5F9F5R('0@;FYT<"]W86ET+69O<BUT97AT(&YN=' O
XM<VUT<"UT;RUU;FEX+71E>'1=(#,I*0H**&1E9G5N(&YN=' O<VUT<"UT;RUU
XM;FEX+71E>'0@;FEL(")<"D-O;G9E<G0@=&AE(&-U<G)E;G0@8G5F9F5R(&9R
XM;VT@4TU44"!T97AT(&9O<FUA="!T;R!5;FEX('1E>'0*9F]R;6%T+B @36]D
XM:69I97,@<&]I;G0N("!2971U<FYS(&YO=&AI;F<N(B H8GET92UC;V1E(")E
XM8HAM/X4E &? /841 ,'"(8C#((AHQ#V%'@#!Q2&(QB"(@@, B,<@B&C(/84R
XM ,'"(8<B(%LT-B!D96QE=&4M8VAA<B Q(&5N9"UO9BUL:6YE(#$S("TQ(&9O
XM<G=A<F0M8VAA<B!B86-K=V%R9"UC:&%R(#$P72 W*2D*"BAD969U;B!N;G1P
XM+W5N:7@M=&\M<VUT<"UT97AT(&YI;" B7 I#;VYV97)T('1H92!C=7)R96YT
XM(&)U9F9E<B!F;W)M(%5N:7@@=&5X="!F;W)M870@=&\@4TU44"!T97AT"F9O
XM<FUA="X@($UO9&EF:65S('!O:6YT+B @4F5T=7)N<R!N;W1H:6YG+B(@*&)Y
XM=&4M8V]D92 B96*(;3^%'0!GP#V%$ # 8XC!((C"8XC#((B" P"(;X8J &C$
XM/88J ,5CB,9CAR(@6S0V(&5N9"UO9BUL:6YE(#$S(&9O<G=A<F0M;&EN92 Q
XM," B#0HB("(N#0HB72 T*2D*"BAD969U;B!N;G1P+W1R>2UX;W9E<B H<V5Q
XM=65N8V4I(")<"E1R>2!U<VEN9R!T:&4@6$]615(@8V]M;6%N9"!T;R!R971R
XM:65V92!H96%D97)S+B(@*&)Y=&4M8V]D92 B"4#'"2% &AC(R<H((<O*"B%1
XM7"*(S"#-/8,X ,X+(8B*SPLA<8B,T&4,7"*(T0DA*=)E#%PBB"F"/0#&B16(
XMQBJ'(B!;;&\@<V5Q=65N8V4@:&D@;FYT<"]C;VYN96-T:6]N(&-H870O9&%T
XM82UM87)K97(@;FYT<"]C86XM>&]V97(@;FEL(&QA<W0@;FYT<"]C;VUM86YD
XM(")83U9%4B(@:6YT+71O+7-T<FEN9R B+2(@;FYT<"]R97-P;VYS92 R,C0@
XM8VAA="]W86ET+69O<BUD;W0M8W)L9B!P<F]C97-S+6)U9F9E<B!N87)R;W<M
XM=&\M<F5G:6]N(&YO=B]P87)S92!D96QE=&4M<F5G:6]N72 Q,RDI"@HH9&5F
XM;6%C<F\@;F]V+W-K:7 M9FEE;&0@;FEL("AB>71E+6-O9&4@(L"'(B!;*'-E
XM87)C:"UF;W)W87)D("()(B!E;VP@*'%U;W1E(&5N9"DI72 Q*2D*"BAD969M
XM86-R;R!N;W8O9FEE;&0@;FEL("AB>71E+6-O9&4@(L"'(B!;*&)U9F9E<BUS
XM=6)S=')I;F<@*'!O:6YT*2 H<')O9VX@*&YO=B]S:VEP+69I96QD*2 H,2T@
XM*'!O:6YT*2DI*5T@,2DI"@HH9&5F;6%C<F\@;F]V+W)E860M:6YT96=E<B!N
XM:6P@(E)E860@86X@:6YT96=E<B!F<F]M('1H92!C=7)R96YT('!O:6YT(&%T
XM('1H92!B=69F97(N(B H8GET92UC;V1E("+ AR(@6RAS=')I;F<M=&\M:6YT
XM("AB=69F97(M<W5B<W1R:6YG("AP;VEN="D@*'!R;V=N("AS:VEP+6-H87)S
XM+69O<G=A<F0@(C M.2(I("AP;VEN="DI*2E=(#$I*0H**&1E9G5N(&YO=B]P
XM87)S92 H<V5Q=65N8V4I(")<"E!A<G-E('1H92!N97=S(&]V97)V:65W(&1A
XM=&$@:6X@=&AE(&-U<G)E;G0@8G5F9F5R+"!A;F0@<F5T=7)N(&$*;&ES="!O
XM9B!H96%D97)S('1H870@;6%T8V@@4T51545.0T4@*'-E92 G;FYT<"UR971R
XM:65V92UH96%D97)S*2XB("AB>71E+6-O9&4@(L'!P<$<&QH896*(#841 &T_
XMA>4 Q\A@R<HAB&!<(B&)$(@-A2D #4 (5X4T  U!B16(@B$ B V%/0 (#4 ]
XMA=X #4&)%8B*RR"(8(D4*8C,S<%<(HD2B K."$F(SR"("M#(8-'2#-,CB&!3
XM7"))B K4R&#1T@S3(XA@4UPB28@*U<A@T=(,TR.(8%-<(DF("M;(8-'2#-,C
XMB&!37"))B K7R&#1T@S3(XA@4UPB28C1T@S3(X@*V,?(8-'2#-,CB&!37"(A
XM28C9((C1V@S&(X78  K;R&#1T@S3(XA@4UPB28@*"T*)$XC<((B""P"(W0LA
XMB1.("RR'(B!;;G5M8F5R(&YI;"!H96%D97(@:&5A9&5R<R!E;VP@<V5Q=65N
XM8V4@="!S=')I;F<M=&\M:6YT(&)U9F9E<BUS=6)S=')I;F<@<VMI<"UC:&%R
XM<RUF;W)W87)D("(P+3DB(&5N9"UO9BUL:6YE(&UA:V4M=F5C=&]R(#@@,"!F
XM;W)W87)D+6-H87(@,2!S96%R8V@M9F]R=V%R9" B"2(@96YD(#(@-2 V(#<@
XM-"!B86-K=V%R9"UC:&%R("()>')E9CH@(B S(&9O<G=A<F0M;&EN92!N<F5V
XM97)S95T@,S$I*0H**&1E9G5N(&YN=' O861D+71O+6AO;VL@*&AO;VLM;F%M
XM92!V86QU92D@*&)Y=&4M8V]D92 BP1C$"B&%#  *2HD0B,4((88E  B%&0 (
XM.88E  @\A24 "$#&/84L  A#B1"("P@^AC@ "PA"B1"("@A,*8<B(%MH;V]K
XM(&YI;"!H;V]K+6YA;64@=F%L=64@8F]U;F1P('-U8G)P(&QA;6)D85T@-"DI
XM"@HH;FYT<"]A9&0M=&\M:&]O:R H<75O=&4@9VYU<RU!<G1I8VQE+7!R97!A
XM<F4M:&]O:RD@*'%U;W1E(&YN=' O87)T:6-L92UG970M>')E9G,I*0H**&1E
XM9G9A<B!G;G5S+6-U<G)E;G0M:&5A9&5R<R!N:6PI"@HH9&5F=6X@;FYT<"]A
XM<G1I8VQE+6=E="UX<F5F<R!N:6P@(EP*1FEL;"!I;B!T:&4@6')E9B!V86QU
XM92!I;B G9VYU<RUC=7)R96YT+6AE861E<G,L(&EF(&YE8V5S<V%R>2X*5&AI
XM<R!I<R!M96%N="!T;R!B92!C86QL960@:6X@)V=N=7,M07)T:6-L92UP<F5P
XM87)E+6AO;VLN(B H8GET92UC;V1E("((PTB&0@#"&65BB,3%PL8CB(S'96!<
XM(HAE8HC(9R')/84E ,K+(88K ,3,(85  ,W.(6*(SR"(",/08-$@B&!<(DDI
XM*8<B(%MG;G5S+6-U<G)E;G0M:&5A9&5R<R!C87-E+69O;&0M<V5A<F-H(&YI
XM;" S('-E87)C:"UF;W)W87)D("(*"B(@96YD(&YA<G)O=RUT;RUR96=I;VX@
XM9&]W;F-A<V4@,3(P(&QO;VMI;F<M870@(EAR968Z(B B"EAR968Z(B!M871C
XM:"UE;F0@,"!F;W)W87)D+6-H87(@8G5F9F5R+7-U8G-T<FEN9R!E;F0M;V8M
XM;&EN95T@,3,I*0H**&1E9G5N(&YN=' O:&5A9&5R<R H<V5Q=65N8V4I("AB
XM>71E+6-O9&4@(L$@B,+#(8C$""&(PL4AB,8((8<B(%MS97%U96YC92!N;G1P
XM+V-L96%R(&UE<W-A9V4@(G)E<75E<W0N+BXB(&YN=' O<V5N9"UH96%D+7)E
XM<75E<W1S(")P87)S:6YG+BXN(B!N;G1P+W!A<G-E+6AE861E<G-=(#8I*0H*
XM*&1E9G5N(&YN=' O<V5N9"UH96%D+7)E<75E<W1S("AS97%U96YC92D@*&)Y
XM=&4M8V]D92 B"(48 ,(@B,,)Q A Q5%<(H@(08D0B((  (<B(%MS97%U96YC
XM92!N;G1P+V-O;FYE8W1I;VX@86-C97!T+7!R;V-E<W,M;W5T<'5T('!R;V-E
XM<W,M<V5N9"US=')I;F<@(DA%040@(B B#0HB72 W*2D*"BAD969U;B!N;G1P
XM+W!A<G-E+6AE861E<G,@*'-E<75E;F-E*2 H8GET92UC;V1E("+!P<$;&A@,
XMA60 Q\@-7"*(BLD-(7&(C,IE#@9<(HC+S&5ES5Q<7"(AB1(ISF4.!EPBB"F(
XM"L\]@UD T TAB(K)#2%QB(S*90X&7"*(T0Q (0A"B1 ISF4.!EPBB"F"6P#2
XM((@,08D4B((& (C3""$KAR(@6VAE861E<G,@;FEL(&-O9&4@;G5M8F5R('-E
XM<75E;F-E(&YN=' O8V]N;F5C=&EO;B!C:&%T+V1A=&$M;6%R:V5R(&-H870O
XM=V%I="UF;W(M<W1R:6YG("(*(B!P<F]C97-S+6)U9F9E<B!N87)R;W<M=&\M
XM<F5G:6]N('-T<FEN9RUT;RUI;G0@8G5F9F5R+7-U8G-T<FEN9R T(&1E;&5T
XM92UR96=I;VX@,C(Q(&-H870O=V%I="UF;W(M9&]T+6-R;&8@;FYT<"]P87)S
XM92UH96%D97(@9F]R=V%R9"UL:6YE(&YR979E<G-E72 Q-2DI"@HH9&5F=6X@
XM;FYT<"]H96%D97(M=F%L=64@;FEL("AB>71E+6-O9&4@(L#!(6*(PL,AB,1@
XMQ2"(:,8]A1< Q\@AB,D@B&?*/H4O ,?((8C'RR&(S&.(@@L B&!37"*'(B!;
XM;6%T8V@M96YD(# @<VMI<"UC:&%R<RUF;W)W87)D("()("(@8G5F9F5R+7-U
XM8G-T<FEN9R!E;F0M;V8M;&EN92 Q,R!D96QE=&4M8VAA<B M,2!F;W)W87)D
XM+6-H87(@*#D@,S(I(#$@,S)=(#$Q*2D*"BAD969U;B!N;G1P+W!A<G-E+6AE
XM861E<B H;G5M8F5R*2 H8GET92UC;V1E("+&Q\%<(L/!'!H8",@-28@(R<A)
XMB&T_A9< RLLA/X,D ,P@@I, S6<ASCV#-  (S] @28*3 ,UG(=$]@T0 "-+0
XM($F"DP#-9R'3/8-4  C4T"!)@I, S6<AU3V#9@ (R=;0("%)@I, S6<AUSV#
XM=@ (V- @28*3 ,UG(=D]@X8 "-K0($F"DP#-9R';/863  C<T"!)B((3 (@(
XM*X<B(%MH96%D97(@;FEL(&-A<V4M9F]L9"US96%R8V@@="!F:65L9',@;G5M
XM8F5R(&UA:V4M=F5C=&]R(#@@," T(&QO;VMI;F<M870@(G-U8FIE8W0Z7%Q\
XM9G)O;3I<7'QX<F5F.EQ<?&QI;F5S.EQ<?&1A=&4Z7%Q\;65S<V%G92UI9#I<
XM7'QR969E<F5N8V5S.B(@9F]R=V%R9"UL:6YE(&1O=VYC87-E(#$Q-2 Q(&YN
XM=' O:&5A9&5R+79A;'5E(#$P,B R(#$R," S(#$P."!S=')I;F<M=&\M:6YT
X9(#$P," U(#$P.2 V(#$Q-" W72 R,BDI"B S
X 
Xend
END_OF_FILE
if test 11533 -ne `wc -c <'nntp.elc.uu'`; then
    echo shar: \"'nntp.elc.uu'\" unpacked with wrong size!
fi
# end of 'nntp.elc.uu'
fi
echo shar: End of shell archive.
exit 0
Technical Details
Message-ID: <FLEE.93Feb3015319@dictionopolis.cs.psu.edu>
Path: arc1-ca.pugleaf.net!sparky!uunet!elroy.jpl.nasa.gov!ames!agate!spool.mu.edu!uwm.edu!psuvax1!flee

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 1016f0,977d20747684ddbe
X-Google-Attributes: gid1016f0,public
X-Google-ArrivalTime: 1993-02-04 22:39:48 PST
Newsgroups: gnu.emacs.gnus
Path: arc1-ca.pugleaf.net!sparky!uunet!elroy.jpl.nasa.gov!ames!agate!spool.mu.edu!uwm.edu!psuvax1!flee
From: flee@cs.psu.edu (Felix Lee)
Subject: A replacement for nntp.el
Message-ID: <FLEE.93Feb3015319@dictionopolis.cs.psu.edu>
Sender: news@cs.psu.edu (Usenet)
Nntp-Posting-Host: dictionopolis.cs.psu.edu
Date: Wed, 3 Feb 1993 06:53:19 GMT
Lines: 1135