me~ TNRKIT.BCK TNRKIT.BCKKBACKUP/LOG/INTERCHANGE/EXCLUDE=(*.BCK,MAKE_KIT.COM) *.* TNRKIT.BCK/SAVE_SET MIKE @wi}V6.1 _VISHNU::  _$1$DUA6: V6.1 ~ ,*[MIKE.PROJ.NEWSREAD.KIT]ALPHA_NEWSREAD.EXE;1+,3./@ 4-0k0123 KPWO56Pc}7&zc}89G@HJ"H h(Ec}0@`4EEc}ALPHA_NEWSREADV1.0A11-14$ $ $  $ $J $( 4V  TWGLIB_0018 CMA$TIS_SHR_0018  DECC$SHR_0014& LIBOTS_001@]|ESYS$PUBLIC_VECTORS_0010 @| H'&0 0 F0   0 ` F 0p0   0   & 0 0 %s QUITQUIT.nntptcpsocketconnectnntp/tcp: Unknown service...using default of %d. %s: Unknown host. #4G~^ ^(GG# B  = > (buZk =b#P@BGb4G1UZkG] ](0#kG#G~tG^^ GG"" B(b1"MJZk="0"B 'AZkG@BGHbtG_ZkG]] 0#kG#P~^^"GGb#_"?"0b#@4G B(bpZk4Gp B(b}pZkG]] #kG0#4G~"^^~޴GGPr.rJEF @P0 @"@,HDP"0 @_A1@@ b#!  G@ GGG b#@`""G b#@" B(b4GuZZk4G@B4GHbTZk B"(b4GkZZk@`b0¤ "4G D`BhbIZkPB"GZk"b#\_Ӑ"?" b#d@B4Gb pZk4GBbpZk@B4GHb4GsTZk"b#DC_"G b#K@"DxDPB%"sZk `B"hb4G]IZk"b#._PB%""fZk"G b#1@" B4G(bZZkGpB"xb4GNZkGD Bb4GoZk4GBboZk@B4GHb4G1TZk@u@" H b#H]@8DDDG@ӉGD%D 0HD? B"(b4GYZk"G b#@uG B"(b4GYZkn"b#_Ӑ"?" b#@4GBboZkB4GboZkG]4G]}ݤ#kG#~^^GG@b#@G  G"01G]] #k#TG~^ ^(~08@޴HPXGGG PBGXb %"GuQZkG`BhbG4GWZk "G0B(%"8bGtGEBZk&, .&HP J0DCpBGxb4GBZkG " 0B`%"8bGtG/BZk WG&,G.&HP J0DC!J GH " ".. /J&/U JBKFCTt@Y 7KԢGCGGOAZkySH&,TG -4GG&HBH Ib8K(DC!v H8GG=tGxZkG+Bb="GGtG6@Zk BbG~ZkD$G .&.0`@JQ &JFCAa@!? DGG] ](}08@ݤHPX`#k@B"Hb4G7KZk G@B"Hb4G/KZk G#TG~TG^^~ (0޴8GGG 0B8bWZkG%@¤`BG$~ZkPBGZk`@pBX$"GxbtG]Zk@X$"X ,TGA HX $G_~Zk 0BG8bGTGVZkG0B8bTGTGVZk,DH @GG]]} (0ݤ8@#kTXx0 0pP`p P`0@ 0@P @TWGLIB@ CMA$TIS_SHR@DECC$SHR@LIBOTS@SYS$PUBLIC_VECTORS%NEWSREADDEC C V4.0-000TRANSFER$BREAK$GO __iscntrl put_server    close_server&    xmain        O  Q K E     #   (          X               Q4    d server_init 4  E  ` getsocket W   W   ^  d  b  l  r  v  v  x  x  x  x H x  y  x  s  s # 8 }   D get_server                 ,  H `__main hyt ,*[MIKE.PROJ.NEWSREAD.KIT]ALPHA_NEWSREAD.OBJ;1+,)'O. /@ 4 D-0k0123KPWO!56M`}7b}89G@HJDDNEWSREADV1.0 4-JAN-1995 17:02DEC C V4.0-000  $ABS$it $CODE$ $LITERAL$$LINK$$DATA$$BSS$ $READONLY$DECC$GA_STDERR DECC$GA_STDINDECC$GXFPRINTFDECC$GXSPRINTF DECC$GETS DECC$PUTS DECC$PERROR DECC$ATOI DECC$EXITDECC$GA___CTYPE DECC$STRLEN DECC$STRCMP DECC$STRCPY DECC$CLOSEHTONS GETHOSTBYNAME GETSERVBYNAME CMA$TIS_ERRNO_GET_ADDR0J SERVER_INIT0J GET_SERVER0J GETSOCKET SER_RD(SER_RD SER_WR(SER_WR0J PUT_SERVERNETWRITE0J CLOSE_SERVER(JMAINSOCKETCONNECTINDEXNETREAD(J`__MAIN DECC$MAIN DECC$EXITOTS$MOVE =| t #4G~^ ^(GG# B  = > (b@Zk =b#P@BGb4G@ZkG] ](0#kG#G~tG^^ GG"" B(b1"@Zk="0"B @ZkG@BGHbtG@ZkG]] 0#kG#P~^^"GGb#_"?"0b#@4G B(b@Zk4Gp B(b@ZkG]] #kG0#4G~"^^~޴GGPr.rJEF @P0 @"@,HDP"0 @_A1@@ b#!  G@ GGG b#@`""G b#@" B(b4G@Zk4G@B4GHb@Zk B"(b4G@Zk@`b0¤ "4G D`Bhb@ZkPB"G@Zk"b#\_Ӑ"?" b#d@B4Gb@Zk4GBb@Zk@B4GHb4G@Zk"b#DC_"G b#K@"DxDPB%"@Zk `B"hb4G@Zk"b#._PB%""@Zk"G b#1@" B4G(b@ZkGpB"xb4G@ZkGD Bb4G@Zk4GBb@Zk@B4GHb4G@Zk@u@" H b#H]@8DDDG@ӉGD%D 0HD? B"(b4G@Zk"G b#@uG B"(b4G@Zkn"b#_Ӑ"?" b#@4GBb@ZkB4Gb@ZkG]4G]}ݤ#kG#~^^GG@b#@G  G"01G]] #k#TG~^ ^(~08@޴HPXGGG PBGXb %"G@ZkG`BhbG4G@Zk "G0B(%"8bGtG@Zk&, .&HP J0DCpBGxb4G@ZkG " 0B`%"8bGtG@Zk WG&,G.&HP J0DC!J GH " ".. /J&/U JBKFCTt@Y 7KԢGCGG@ZkySH&,TG -4GG&HBH Ib8K(DC!v H8GG=tG@ZkG+Bb="GGtG@Zk BbG@ZkD$G .&.0`@JQ &JFCAa@!? DGG] ](}08@ݤHPX`#k@B"Hb4G@Zk G@B"Hb4G@Zk G#TG~TG^^~ (0޴8GGG 0B8b@ZkG%@¤`BG$@ZkPBG@Zk`@pBX$"GxbtG@Zk@X$"X ,TGA HX $G@Zk 0BG8bGTG@ZkG0B8bTGTG@Zk,DH @GG]]} (0ݤ8@#k4+$GH DECC$MAIN4,<b# ` DECC$MAIN4+D@H DECC$MAIN4#XGl DECC$EXIT4$`b#` DECC$EXIT4#h@l DECC$EXIT4 GDECC$GXSPRINTF4 b#DECC$GXSPRINTF4 @DECC$GXSPRINTF4G DECC$STRLEN4@ DECC$STRLEN4 GNETWRITE4 b#NETWRITE4 @NETWRITE4 TGd DECC$CLOSE4Xb# DECC$CLOSE4 `@d DECC$CLOSE4 lG| DECC$CLOSE4pb# DECC$CLOSE4 x@| DECC$CLOSE4!G DECC$PUTS4"b# DECC$PUTS4!@ DECC$PUTS4#G DECC$EXIT4$b# DECC$EXIT4#@ DECC$EXIT 4!G DECC$PUTS4"b# DECC$PUTS4!@ DECC$PUTS4'G DECC$GETS4(b# DECC$GETS4'@ DECC$GETS4%G DECC$STRCMP4%@ DECC$STRCMP4 (G< DECC$CLOSE44b# DECC$CLOSE4 8@< DECC$CLOSE4 @GP DECC$CLOSE4Hb# DECC$CLOSE4 L@P DECC$CLOSE4#PGd DECC$EXIT4$Xb# DECC$EXIT4#`@d DECC$EXIT4%G DECC$STRCMP4%@ DECC$STRCMP4'G DECC$GETS4(b# DECC$GETS4'@ DECC$GETS4%G DECC$STRCMP4%@ DECC$STRCMP4!G DECC$PUTS4"b# DECC$PUTS4!@ DECC$PUTS4)G$ DECC$ATOI4*b# DECC$ATOI4) @$ DECC$ATOI4 4GD DECC$CLOSE48b# DECC$CLOSE4 @@D DECC$CLOSE4 HGX DECC$CLOSE4Pb# DECC$CLOSE4 T@X DECC$CLOSE4#XGl DECC$EXIT4$`b# DECC$EXIT4#h@l DECC$EXIT4!G DECC$PUTS4"b# DECC$PUTS4!@ DECC$PUTS4!G DECC$PUTS4"b# DECC$PUTS4!@ DECC$PUTS4 8GH DECC$CLOSE4@b# DECC$CLOSE4 D@H DECC$CLOSE4 HG\ DECC$CLOSE4Tb# DECC$CLOSE4 X@\ DECC$CLOSE40GL GETSERVBYNAME48b# GETSERVBYNAME4H@L GETSERVBYNAME,TGhHTONS,Xb#HTONS,d@hHTONS4pGDECC$GXFPRINTF4xb#DECC$GXFPRINTF4@DECC$GXFPRINTF4G GETHOSTBYNAME4b# GETHOSTBYNAME4@ GETHOSTBYNAME4GDECC$GXFPRINTF4b#DECC$GXFPRINTF4@DECC$GXFPRINTF4DGtOTS$MOVE4p@tOTS$MOVE,GSOCKET, b#SOCKET,@SOCKET,GCONNECT,b#CONNECT,@CONNECT<GCMA$TIS_ERRNO_GET_ADDR<b#CMA$TIS_ERRNO_GET_ADDR<@CMA$TIS_ERRNO_GET_ADDR4xG DECC$PERROR4b# DECC$PERROR 4@ DECC$PERROR4G DECC$PERROR4b# DECC$PERROR4@ DECC$PERROR,G INDEX,b#INDEX, @ INDEX4 G DECC$STRCPY4 @ DECC$STRCPY4 G, DECC$STRLEN4( @, DECC$STRLEN,0 GL NETREAD,@ b#NETREAD,H @L NETREAD,p G INDEX, b#INDEX, @ INDEX4 G DECC$STRCPY4 @ DECC$STRCPY, G INDEX, b#INDEX, @ INDEX, G INDEX, b#INDEX, @ INDEX4 G DECC$STRLEN4 @ DECC$STRLEN =0 ;=@| H;0INDEX7SER_RDP DECC$STRLEN DECC$STRCPYNETREAD=0 ;=0  DECC$GXSPRINTF7SER_WR NETWRITE=0 ;=   DECC$CLOSE=0 ;=` 7DECC$GA_STDERR0DECC$GXFPRINTF DECC$PERROR GETSERVBYNAMEHTONS GETHOSTBYNAMECONNECT CMA$TIS_ERRNO_GET_ADDR8OTS$MOVESOCKET=0 ;=  =0 ;= ! DECC$PUTS7 DECC$GA_STDIN # DECC$EXIT% DECC$STRCMP' DECC$GETS) DECC$ATOI=0 ;=0 + DECC$MAIN =%s =QUIT==QUIT =.(=nntp0=tcp8=socket@=connect4P=@2nntp/tcp: Unknown service...using default of %d. = %s: Unknown host. =6 > >=.&%NEWSREADDEC C V4.0-000? ?= 4=TRANSFER$BREAK$GO# #= __iscntrl =  = 44= put_server4="  $ $= 4: := 4=  = 44= close_server4=/'&   $ $= 4: := x4=  = 44= main4=e]        O  Q K E     #   (          X               Q4$ $= 4. .=  4=  = . .=  4=  = . .=  4=  = : := d4=  = 44= server_init4=' 4  E $ $= 4: := 4= `8 8= 44= getsocket4= W   W   ^  d  b  l  r  v  v  x  x  x  x H x  y  x  s  s # 8 }  $ $= 4: := D4=  = 44= get_server4=                 ,$ $= 4. .=  4=  = : := H 4= ` `= 4`4= __main4: := h4=  =  `$*[MIKE.PROJ.NEWSREAD.KIT]BUILD.COM;23+,wN)./@ 4WT-0k0123KPWO56](}7WN(}89G@HJ$!,$! Build.com - build the NEWSREAD.EXE file.$!$! To build on VAX:$! $! @BUILD$!$! To build on AXP:$!$! @BUILD AXP$!$!!$ @twg$tcp:[netdist.misc]def.com$ if (p1 .eqs. "AXP")$ thenW$ CompOps1 = "/DECC/STANDARD=VAXC/PREFIX_LIBRARY_ENTRIES=(ALL_ENTRIES, EXCEPT=" + -F "(accept, bind, connect, listen, select, shutdown, socket," + - J "recv, send, recvfrom, recvmsg, sendto, sendmsg, readv," + -? "writev, gethostname, sethostname, getpeername, getsockname,"G$ CompOps2 = "getsockopt, setsockopt, getnetbyname, getnetent," + -F "setnetent, endnetent, getprotobyname, getprotobynumber," + -9 "getprotoent, setprotoent, endprotoent, getservbyname,"L$ CompOps3 = "getservbyport, getservent, setservent, endservent," + -F "gethostbyname, gethostbyaddr, gethostent, sethostent," + -E "endhostent, inet_addr, inet_lnaof, inet_makeaddr, inet_netof," + -: "inet_ntoa, inet_network, htonl, htons, ntohl, ntohs) )"-$ CompOps = CompOps1 + CompOps2 + CompOps3$ Name = "ALPHA_NEWSREAD"$ else+$ define LNK$LIBRARY SYS$LIBRARY:VAXCRTL$ Name = "NEWSREAD"$ CompOps = ""$ endif$!,$ cc /object='Name'.OBJ'CompOps' newsread.c$!:$ link/executable='Name'.EXE 'Name'.OBJ, sys$input/option%twg$tcp:[netdist.etc]twglib.exe/share$!$ exit$*[MIKE.PROJ.NEWSREAD.KIT]CONFIG.COM;8+,Y!./@ 4b-0k0123KPWO566p7&89.G@HJ$!A$! CONFIG.COM - Help a user create and maintain the GROUPS. and 6$! various group files for the NEWS.TPU system. Use5$! of this procedure is optional. The files can be5$! maintained manually using any text editor if you $! prefer.$!D$! Copyright 1993 The Wollongong Group, Inc. All rights reserved.$!K$! You may distribute this file as part of the TPU-based newsreader systemL$! from The Wollongong Group, Inc. provided that such distribution is made $! free of charge.$!O$------------------------------------------------------------------------------$!!)$ old_control = f$environment("CONTROL")$ set nocontrol=Y$!$! Set defaults$!$ grpfile = "GROUPS."$ grpext = ".GROUP"$ newsdir = "NEWS$DIR"$!>$! Files are kept in NEWS$DIR. This logical must be defined.$!+$ if (f$trnlnm( "NEWS$DIR",,,,,) .eqs. "")$ then$ write sys$output " "$ write sys$output " "`$ write sys$output " You must define the logical ''newsdir' to point to your news reader"]$ write sys$output " directory. This is the directory where the all newsreader files"_$ write sys$output " are kept. The ''grpfile' file, individual newsgroup files, and theD$ write sys$output " .SIGNATURE or TAGS.DAT file(s) (if any).$ write sys$output " "^$ write sys$output " You can create the logical with the following command (modified toE$ write sys$output " fit your actual configuration of course):$ write sys$output " "W$ write sys$output " $ assign/nolog DUA0:[MIKE.NEWSREADER] ''newsdir'"$ write sys$output " "$ goto ABORT$ endif$$ olddir = f$environment("DEFAULT")$ set default 'newsdir'=$ if (old_control .nes. "") then set control=('old_control')$ on CONTROL_Y then goto EXIT$!$ type sys$input0 =========================================( C O N F I G U R E N E W S R E A D E R0 =========================================/ Press '?' at any prompt for assistance.$!P$! First thing we need to know is if the user has a GROUPS. file already. I.E.<$! is this an initial install, or a group addition or edit?$!=$ if (f$search("''grpfile'") .eqs. "") then goto NEW_INSTALLP$!------------------------------------------------------------------------------3$! Not a new install. Find out what we are to do.$! $GROUP_MAINT:$ type sys$input 1. Add Newsgroup 2. Delete Newsgroup 3. Re-initialize Newsgroup Q. Quit this procedure#$ inquire/nopunct ans " Choice: ",$ ans = f$edit(ans, "upcase,trim,compress")$ if (ans .eqs. "?") $ then$ type/page sys$inputDEnter one of '1', '2', '3', or 'Q' to select the operation you want.6The functions performed by the various operations are:K Add Newsgroup: Add a new newsgroup to the current configuration.2 Will ask for the name of the newsgroup (i.e.  "comp.os.vms")G Delete Newsgroup: Remove an existing newsgroup from the current8 configuration. The current status of the newsgroup5 will be forgotten and the newsgroup will need to0 be added before messages can be read again.GRe-initialize Newsgroup: Reset the status of the Newsgroup so that the6 last-read message pointer is reset to the lowest-3 numbered valid message, and all information on3 which messages have been read already is lost.< Quit: Exit the procedure and return to the DCL prompt.6$ inquire/nopunct ans "Press RETURN to continue..." $ ans = ""$ goto GROUP_MAINT$ endif*$ if (ans .eqs. "") then goto GROUP_MAINT($ if (ans .eqs. "Q") then goto ALL_DONE:$ if (ans .lt. 1) .or. (ans .gt. 3) then goto GROUP_MAINT$! $GET_GNAME:$ write sys$output " "2$ inquire/nopunct groupname "Name of the group: ";$ groupname = f$edit(groupname, "lowercase,trim,compress"),$ if groupname .eqs. "" then goto GET_GNAME$ if groupname .eqs. "?"$ then$ type/page sys$inputAPlease enter the name of the newsgro up you want added, deleted orOre-initialized. Newsgroups have names such as "comp.os.vms" or "rec.org.sca". NYou may not add a group you already have configured, and you may not delete orIre-initialize any group that is not already a part of your configuration.6$ inquire/nopunct ans "Press RETURN to continue..." $ ans = ""$ goto GET_GNAME$ endif$!C$! Modify the groupname to find the filename we use for the group.$!$ filename = groupname$! $DOTLOOP:%$ dotloc = f$loP_~ TNRKIT.BCKY!0k$[MIKE.PROJ.NEWSREAD.KIT]CONFIG.COM;8bH> cate( ".", filename ):$ if (dotloc .ge. f$length(filename)) then goto DOTS_GONE1$ tmp = f$extract(0, dotloc, filename) + "_" + -3 f$extract(dotloc+1, f$length(filename), filename)$ filename = tmp$ goto DOTLOOP$! $DOTS_GONE:N$ if (f$locate(".", grpext) .ge. f$length(grpext)) then grpext = "." + grpext>$ filename = f$edit("''filename'''grpext'", "lowercase,trim")$!$! Dispatch by command$! $ goto 'ans'$!$1: ! add newsgroup($ if (f$search("''filename'") .nes. "")$ then$ write sys$output ""b$ write sys$output "''groupname' is already in the current configuration and can not be added."$ write sys$output ""$ goto GROUP_MAINT$ endif>$ open/write/error=OPEN_GROUPFILE_ERROR_W filechan 'filename'"$ write filechan "''groupname' 0"$ close/nolog filechan:$ open/append/error=OPEN_GROUPS_ERROR_W grpchan 'grpfile'$ write grpchan "''filename'"$ close/nolog grpchan$ write sys$output ""Q$ write sys$output "Newsgroup ''groupname' has been added to the configuration."$ write sys$output ""$ goto GROUP_MAINT$!A$! delete newsgroup. Remove the filename from the GROUPS. file,$! then delete the group file.$!$2:6$ open/read/error=OPEN_GROUPS_ERROR grpchan 'grpfile'@$ open/write/error=OPEN_TEMP_GROUPS_ERROR_W filechan GROUP.TEMP$! $COPYLOOP:"$ read/end=COPY_DONE grpchan lineJ$ if f$locate("''filename'", line) .lt. f$length(line) then goto COPYLOOP$ write filechan "''line'"$ goto COPYLOOP$! $COPY_DONE:$ close/nolog grpchan$ close/nolog filechan%$ delete/nolog/noconfirm 'grpfile';* $ rename GROUP.TEMP;0 'grpfile'O$ if f$search("''filename'") .nes. "" then delete/nolog/noconfirm 'filename';*$ write sys$output ""U$ write sys$output "Newsgroup ''groupname' has been deleted from the configuration."$ write sys$output ""$ goto GROUP_MAINT$!>$! Re-init. Make sure the group exists, then just delete and$! re-create the group file.$3: ($ if (f$search("''filename'") .eqs. "")$ then$ write sys$output ""I$ write sys$output "''groupname' is not in the current configuration."$ write sys$output ""$ goto GROUP_MAINT$ endif&$ delete/noconfirm/nolog 'filename';*>$ open/write/error=OPEN_GROUPFILE_ERROR_W filechan 'filename'"$ write filechan "''groupname' 0"$ close filechan$ write sys$output ""E$ write sys$output "Newsgroup ''groupname' has been re-initialized."$ write sys$output ""$ goto GROUP_MAINT$! $ALL_DONE: $ goto EXITP$!------------------------------------------------------------------------------$!$EOF_GRP_INIT:$ close/nolog grpchan$ type sys$input BIncomplete installation found. Performing new installation now...0$ if (f$search("''grpfile';*") .nes. "") then -# delete/nolog/noconfirm 'grpfile';*$ goto FINISH_INSTALL$! $NEW_INSTALL:$ type sys$inputFNo newsgroup info was found, so this will be an initial installation. $FINISH_INSTALL:9$ open/write/error=OPEN_GROUPS_ERROR_W grpchan 'grpfile'$ close/nolog grpchan$ goto GROUP_MAINTP$!------------------------------------------------------------------------------$!$OPEN_TEMP_GROUPS_ERROR_W:9$ write sys$output "Error opening GROUP.TEMP for write." $ goto EXIT$!$OPEN_GROUPS_ERROR:8$ write sys$output "Error opening ''grpfile' for read." $ goto EXIT$!$OPEN_GROUPS_ERROR_W:9$ write sys$output "Error opening ''grpfile' for write." $ goto EXIT$!$OPEN_GROUPFILE_ERROR_W::$ write sys$output "Error opening ''filename' for write." $ goto EXIT$!$ABORT:($ write sys$output "Procedure aborted." $ goto EXIT$!$EXIT:$ close/nolog grpchan$ close/nolog filechan$ set default 'olddir'=$ if (old_control .nes. "") then set control=('old_control')$ exit"*[MIKE.PROJ.NEWSREAD.KIT]DOC.MEM;13+,L''.(/@ 4M((-0k0123KPWO)562:7F:89G@HJ    1 CREDITS  M This newsreader setup was created from NEWS.TPU and NEWSREADER.C, an M EVE-based newsreader and news server communication program, both by M Keith Lewis (klewis@mitre.org). Additional features, editing, and M comments were added to these files, and additional doc and the config M procedure written, by Mike Bartman of The Wollongong Group ! (mike@eco.twg.com - 1993).     2 INTRODUCTION  M TPU-NewsReader (TNR) is a TPU-based Usenet News reader system. It M allows posting, reading and responding to messages in Usenet M Newsgroups. It will also allow responses to articles to be sent, or M copies of articles to be forwarded, through mail. TNR is not a news M server, just a news reader. You must have a nntp news server on a M system accessable to the system you are running TNR from and your D system must be configured to allow access to the nntp server.     3 REQUIREMENTS FOR USE  M There are several requirements that must be met for TNR to function.  These are:  & o You must be running OpenVMS  ' o Your system must support EVE  < o You must be able to compile and link NEWSREADER.C  : o Your news server must support the XHDR command.  M o Your network config files must be set up to support access to the , news server (service name "nntp")      4 INSTALLATION  ' Setting up TNR is fairly simple:  M 1. Unpack the TNR saveset into a convenient directory, if you haven't  already done so.  M 2. Build the NEWSREADER.EXE (ALPHANEWSREADER>EXE for AXP) image from M NEWSREADER.C (an object file and linked executable, both built M under OpenVMS 6.1 on VAX and AXP, are provided. The link was done M against the Wollongong sharabl8e library (twglib.exe) to get the M socket routines. If these will work on your system you can skip M the build or compile). A build can be accomplished by invoking  H Page 2   M the BUILD.COM procedure provided. By default, BUILD.COM builds M for VAX, if you need to build on an AXP system just include the 7 parameter "AXP" on the BUILD.COM invocation.  M 3. Define the foreign command for running the NEWSREADER.EXE image. . This command is defined as follows:  @ $ nr == "$ :[]NEWSREAD.EXE"  Or, for AXP machines:  F $ nr == "$ :[]ALPHA_NEWSREAD.EXE"   M It might be a good idea to put this definition into your LOGIN.COM  or SYLOGIN.COM file.  M 4. To simplify use of the NEWS.TPU routines it is advisable to create M a section file. To do this use the following commands ( means ; to enter an EVE command by pressing the DO key):  , 1. $ EDIT/TPU NEWS.TPU  ( 2. EXTEND ALL  4 3. SAVE EXTENDED EVE news  , 4. Control-Z (to exit)   M This will result in a file called NEWS.TPU$SECTION. When you run M TPU to read news you should use the command "$ M EDIT/TPU/SECTION=:[]NEWS.TPU$SECTION", or set up the < TPU$SECTION logical to point to the section file.  M 5. The system installation is now complete, however each user will M need to invoke CONFIG.COM at least once to create the GROUPS. and M various newsgroup data files. Each user will also need to create M a logical "NEWS$DIR" to points to an account-specific location : where the newsreader data files are to be kept.      5 CONFIGURATION  M The list of newsgroups a given user is subscribed to is kept in a file M called "GROUPS.". This file is in the NEWS$DIR directory. The format M of this file is a simple one line per newsgroup, and the line contains M only the name of the group's data file. The GROUPS. file can be @ created with the editor or with the CONFIG.COM procedure.  M Each newsgroup has an associated group data file. The name of the M file is the name of the newsgroup (with the periods changed to M underscores). The first line of this file contains the name of the  H Page 3   M newsgroup (i.e. "comp.os.vms"), and the number of the highest M numbered article known to date. Each remaining line in the file, if = any, consists of an article number and a subject line.  M CONFIG.COM makes adding newsgroups, deleting newsgroups and M re-initializing newsgroups (i.e. clearing out the known messages for M a group) very simple. You may change the contents of the GROUPS. and M various group files using any ASCII text editor if you want to, but M until you understand how the system works it will be safest to let M NEWS.TPU and CONFIG.COM make all the changes to the GROUPS. and  various group files.  M TNR supports the use of signatures. There is a file in the NEWS$DIR M directory called "SIGNATURE.". The contents of this file are appended M to messages posted or to articles replied to through mail. If you M don't want to use a signature file you may delete it. The default M SIGNATURE. file should be edited before use. The contents are up to you!  M TNR also supports taglines. The file TAGS.DAT contains a few starter M taglines, and you may add to or delete from this file as you wish. M Taglines are added to the end of messages posted to newsgroups, but M not to netmail messages. Taglines should be a single line in the M TAGS.DAT file (lines longer than 80 characters will be wrapped M automatically). TNR puts the tagline between lines of "=" and "-". M Taglines are used from the top of the file and as they are used they M are moved to the end of the TAGS.DAT file so each will be used in turn M before they begin repeating. If you invent or discover a new tagline M you would like to add to your list, just put it in the TAGLINE buffer M (or add it to the TAGS.DAT file if you are not using NEWS.TPU at the M time). If you do not wish to use taglines simply delete the TAGS.DAT file.    6 USE   6.1 Getting TNR Started  M Once you have TNR installed and configured you are ready to run it and M read a few articles. Run TPU with the proper section file (or load M the NEWS.TPU file and extend the editor yourself). Press the DO key M and enter the following command to start the news reader (the example M command assumes that "NEWSNODE" is the name of the nntp machine. 0 Substitute the name of your server node):  , TPU start_news("NEWSNODE")  M This will get the server connection up, configure everything, and load ' the GROUPS. file into a buffer.  M If you want to automate things a bit more you should define a symbol M and create an init file. Create a file called M "NEWS$DIR:EVE$INIT.EVE", and put the line "TPU start_news("NEWSNODE")" M (or whatever your news server nodename is) into the file. Create a  H Page 4   6 symbol (in your login.com for example) such as:  A READNEWS :== EDIT/TPU/SECTION=NEWS$DIR:NEWS.TPU$SECTION  M (Note: this assumes that the section file is in the NEWS$DIR dM directory. Adjust as necessary.) Setting default to NEWS$DIR and wM typing READNEWS should get you reading news with no further work. If M this is still too much typing you can create a command procedure to eM change the default directory and execute the READNEWS command for you. oM There are other posibilities for setting up the TPU init and section eM files. See the TPU documentation if you need to use a different t method.  M To read news once TNR is running, position the cursor to the line with rM the name of the group you want to read and press Control-K. There rM will be a brief delay and you will see a list of all available B articles for the selected group in a buffer on your screen.     6.2 Reading Articles  M To read an article position the cursor to the article and press M Control-G. The article will be loaded into a buffer and you can read tM it using the normal TPU editing capabilities (page up, page down, YM arrows, find, etc.). To go to the next article you can press M Control-K to return to the message list buffer then choose another M with Control-G, or just press Control-N to go to the next article in fM the thread or group (TNR will try to follow threads where possible). M When you have read all the articles in the group you are returned to M the GROUPS. buffer to choose another group. If you want to return to eM the GROUPS. buffer before reading all available messages just press NM Control-K once or twice (if you are reading a message the first .M Control-K will take you to the message list buffer, the second will VM take you to the GROUPS. buffer. If you are already in the message h0 list buffer you only need one Control-K).  M If you are reading a message and want to read a message in the iM "References: " list, position the cursor to the message ID you want nM to read and press Control-G. The Control-G will grab the word the 2M cursor is on and use it as a message ID, so be sure the ID is isolated M from other IDs, commas, or whatever before you press the Control-G. lM This function will work for message IDs or article numbers in any 3M buffer, though in the message list buffer the word used will be the  first word on the line.  M If you find an article, or portion of an article, that is ROT-13 M encrypted you can read the encrypted text very simply. Select the eM encrypted text (using the normal TPU selection mechanism) and press hM the keypad '5' key (KP5). The selected text will be decrypted. If M you wish to ROT-13 encrypt some text, simply select it and press KP5. M ROT-13 is nice in that the same mechanism that encrypts plain text, M also decrypts coded text. To allow you to reverse the process the M selection remains in place after encryption or decryption. If you D want to cancel the selection just press the SELECT key again.  H Page 5   M To mark an article as read, delete the line in the message list uM buffer. Control-N does this for you automatically, but Control-K and PM Control-G do not. This can be useful if you start to read an article sM and decide you want to come back to it later. Just use Control-K, and e3 move the cursor to another article yourself. M   = 6.3 Re-constructing Multi-part And Uuencoded Messages t M There are some newsgroups (such as alt.binaries.pictures) where tM exchanges of binary pictures (.GIF, .JPG, etc.) are done by uuencoding aM the picture file. When an encoded file is too long, it is broken up eM into smaller parts and each part is posted as a seperate article. lM Usually the subject line will let you know the ordering of the parts. M The problem is collecting the pieces, and decoding the thing back into lM a binary form. TNR has features to help with this, but, alas, due to eM the many ways of handling such files it can not be made fully u automatic.  M In TNR the basic idea is to initialize, grab all the pieces, and o convert. r M Initialization resets counters, deletes any leftover temp files and aM generally gets things ready for grabbing. The init routine is called M using the keypad '7' key (KP7). Press it and you will get a message ) "uu initialized" when it is ready.  M The next phase is grabbing. You need to grab each part and must do so aM in the correct order, since as each part is grabbed it is appended to sM a file. Getting things out of order will put the decoded bytes in the .M wrong order and that is unlikely to be what you want. To grab a hM piece, read the message containing the part (Control-G or Control-N), M then manually trim off any header or trailer info that is not wanted tM (for uuencoded files everything before the "begin " line and after the M "end" line). Hint: You can make good use of the LEARN function if M there are lots of parts... By the way, you might want to check the M file name on the "begin " line to make sure it is legal for VMS. It M usually is, but sometimes you will see a full Unix path specification, M and this will cause lots of problems! It should be pretty easy to M find the start and end of the encoded data since there is usually a M "cut here" line of some sort. (If people would standardize the cut wM lines the grab step could be made much more automatic...). Once you M have the message edited, press the keypad '8' key (KP8). After a oM brief delay you will get the message "uu part grabbed." at the bottom iM of the screen. The part has been appended to the end of the growing e4 file and you are ready to grab the next part.  M The last phase comes once you have grabbed all the parts that make up fM the encoded file. At this point you simply press the keypad '9' key i' (KP9) and the file is converted! b M The conversion step is simple, but requires some setup on your part. M What TNR does is call a command procedure called aM NEWS$DIR:MULTI_MSG_COMPLETE.COM, providing the name of the appended ) H Page 6   M message file as a parameter. It is up to the MULTI_MSG_COMPLETE.COM oM procedure to handle the actual conversion and any other activities aM (such as moving the decoded file out of the NEWS$DIR directory) WM desired. It would be nice if this could be standardized as well, but nM since I have no knowledge of what decrypter you might be using, or dM what you want done with the results, it seemed easiest to just provide tM this mechanism to let you set things up the way you like. Just be OM sure that when the NEWS$DIR:MULTI_MSG_COMPLETE.COM procedure exits, aM that you have done what you need to do, since the appended file will u be deleted immediately.     6.4 Exiting TNR  M To exit press Control-Z. You may be asked about saving various EM buffers. In general you should reply "Y" to any buffers associated vM with the GROUPS. or *.GROUP files, or the TAGS.DAT file and "N" to  the others.    ' 6.5 Posting Replies To Articles  M If you want to post a reply to an article you are reading! press PM Control-P. This will put you and the article into the post buffer. hM Your SIGNATURE. (if any) and a tagline (if any) will be added to the sM message automatically at this point. Make whatever changes you like M (best to leave the header alone...) then press Control-P again to send nM it. You will have to wait until the news server has accepted the nM article, so be patient. The return status from the news server will M be shown on the screen when the message post attempt is complete. i4 "200 Article Posted" is what you want to see.    0 6.6 Replying To Articles Through Netmail  M If you want to reply to an article through netmail rather than news sM use the Control-B key. This works just like the Control-P key. That M is, press Control-B, edit the reply any way you like, then press rM Control-B again to send it. Reply sends through Pony Express, so if lM you are using a different mailer you may need to change the reply and ) start_news procedures in NEWS.TPU. u   1 6.7 Forwarding An Article Through Netmail s M If you want to forward the article through mail, but not to the author aM (which is what the Control-B reply command does), use the forward M command (Control-F). When you press Control-F you are asked to enter tM the address of the recipient you want to forward the article to. a> Enter the address as you would if you were in VMS Mail:   H Page 7   4 ECOVAX::mike   M If you need to include double quotes (") in your address specification (M you need to doubled them (i.e. anywhere you would normally use a oM double quote, use two of them). For instance to foward an article A through Pony Express to mike@eco.twg.com you should enter: y ; PONY%""mike@eco.twg.com"" s   8 6.8 Adding More Newsgroups To Your Configuration  M If you want to see what newsgroups are available from your news CM server, invoke the LIST_GROUPS() TPU function, or press Control-J (for sM "join group"). There will be a brief delay, then you will be placed mM into a buffer containing a list of all available newsgroups. To add a lM group, place the cursor on the line containing the name of the group tM and press Control-J again. The line will be replaced by a message lM saying the group has been added, or one stating that the group was M already part of your configuration. The alternative is to use the lM CONFIG.COM DCL procedure or create and modify the configuration files d with your text editor. 5   8 6.9 Removing A Newsgroup From Your Configuration  M If you want to copmpletely remove a newsgroup from your configuration, iM use Control-K to get to the "GROUPS." buffer, and place the cursor on rM the group you want to remove, then invoke the DEL_GROUP() TPU nM function, or press Control-D (for "delete group"). There may be a cM brief delay, then you will get a message saying the froup has been M removed. The alternative is to use the CONFIG.COM DCL procedure or rG delete and modify the configuration files with your text editor. .    7 HAVE FUN! t M That's pretty much it. If you have any questions or suggestions (with A code ;-) you can mail them to mike@eco.twg.com. Have fun! it later. Just use Control-K, and e3 move the cursor to another article yourself. M   = 6.3 Re-constructing Multi-part And Uuencoded Messages t M There are some newsgroups (such as alt.binaries.pictures) where tM exchanges of binary pictures (.GIF, .JPG, etc.) are done by uuencoding aM the"*[MIKE.PROJ.NEWSREAD.KIT]DOC.RNO;21+,(.$/@ 4U$!-0k0123KPWO"56757w)689G@HJ.paragraph 0,1,2.ap.lm 5.rm 75 .hl 1 CreditsO This newsreader setup was created from NEWS.TPU and NEWSREADER.C, an EVE-basedEnewsreader and news server communication program, both by Keith LewisD(klewis@mitre.org). Additional features, editing, and comments wereMadded to these files, and additional doc and the config procedure written, by?Mike Bartman of The Wollongong Group (mike@eco.twg.com - 1993)..hl 1 IntroductionITPU-NewsReader (TNR) is a TPU-based Usenet News reader system. It allowsOposting, reading and responding to messages in Usenet Newsgroups. It will alsoNallow responses to articles to be sent, or copies of articles to be forwarded,Fthrough mail. TNR is not a news server, just a news reader. You mustLhave a nntp news server on a system accessable to the system you are runningOTNR from and your system must be configured to allow access to the nntp server..hl 1 Requirements for UseE There are several requirements that must be met for TNR to function. These are: .list, "o".le;You must be running OpenVMS .le;Your system must support EVE5.le;You must be able to compile and link NEWSREADER.C3.le;Your news server must support the XHDR command.Q.le;Your network config files must be set up to support access to the news server(service name "nntp") .end list.hl 1 Installation! Setting up TNR is fairly simple:.listN.le;Unpack the TNR saveset into a convenient directory, if you haven't alreadydone so.G.le;Build the NEWSREADER.EXE (ALPHA_NEWSREADER>EXE for AXP) image from PNEWSREADER.C (an object file and linked executable, both built under OpenVMS 6.1Pon VAX and AXP, are provided. The link was done against the Wollongong sharableLlibrary (twglib.exe) to get the socket routines. If these will work on yourJsystem you can skip the build or compile). A build can be accomplished byLinvoking the BUILD.COM procedure provided. By default, BUILD.COM builds forNVAX, if you need to build on an AXP system just include the parameter "AXP" onthe BUILD.COM invocation.J.le;Define the foreign command for running the NEWSREADER.EXE image. Thiscommand is defined as follows:.literal/ $ nr == "$ :[]NEWSREAD.EXE"Or, for AXP machines:5 $ nr == "$ :[]ALPHA_NEWSREAD.EXE" .end literalF It might be a good idea to put this definition into your LOGIN.COM orSYLOGIN.COM file.P.le;To simplify use of the NEWS.TPU routines it is advisable to create a sectionHfile. To do this use the following commands ( means to enter an EVE command by pressing the DO key):.lm +10.list.le;$ EDIT/TPU NEWS.TPU.le; EXTEND ALL.le; SAVE EXTENDED EVE news.le;Control-Z (to exit) .end list.lm -10N This will result in a file called NEWS.TPU$SECTION. When you run TPU to readTnews you should use the command "$ EDIT/TPU/SECTION=:[]NEWS.TPU$SECTION", ?or set up the TPU$SECTION logical to point to the section file.K.le;The system installation is now complete, however each user will need toPinvoke CONFIG.COM at least once to create the GROUPS. and various newsgroup dataPfiles. Each user will also need to create a logical "NEWS$DIR" to points to an Kaccount-specific location where the newsreader data files are to be kept. .end list.hl 1 ConfigurationN The list of newsgroups a given user is subscribed to is kept in a file called8"GROUPS.". This file is in the NEWS$DIR directory. TheMformat of this file is a simple one line per newsgroup, and the line containsMonly the name of the group's data file. The GROUPS. file can be created with,the editor or with the CONFIG.COM procedure.O Each newsgroup has an associated group data file. The name of the file is thePname of the newsgroup (with the periods changed to underscores). The first lineMof this file contains the name of the newsgroup (i.e. "comp.os.vms"), and theMnumber of the highest numbered article known to date. Each remaining line inEthe file, if any, consists of an article number and a subject line. L CONFIG.COM makes adding newsgroups, deleting newsgroups and re-initializingOnewsgroups (i.e. clearing out the known messages for a group) very simple. YouNmay change the contents of the GROUPS. and various group files using any ASCIIQtext editor if you want to, but until you understand how the system works it willPbe safest to let NEWS.TPU and CONFIG.COM make all the changes to the GROUPS. andvarious group files.E TNR supports the use of signatures. There is a file in the NEWS$DIRIdirectory called "SIGNATURE.". The contents of this file are appended toMmessages posted or to articles replied to through mail. If you don't want toNuse a signature file you may delete it. The default SIGNATURE. file should be/edited before use. The contents are up to you!P TNR also supports taglines. The file TAGS.DAT contains a few starter taglines,Oand you may add to or delete from this file as you wish. Taglines are added toPthe end of messages posted to newsgroups, but not to netmail messages. TaglinesMshould be a single line in the TAGS.DAT file (lines longer than 80 charactersNwill be wrapped automatically). TNR puts the tagline between lines of "=" andN"-". Taglines are used from the top of the file and as they are used they areNmoved to the end of the TAGS.DAT file so each will be used in turn before theyObegin repeating. If you invent or discover a new tagline you would like to addOto your list, just put it in the TAGLINE buffer (or add it to the TAGS.DAT fileOif you are not using NEWS.TPU at the time). If you do not wish to use taglines simply delete the TAGS.DAT file. .hl 1 Use.hl 2 Getting TNR startedN Once you have TNR installed and configured you are ready to run it and read aNfew articles. Run TPU with the proper section file (or load the NEWS.TPU fileUand extend the editor yourself). Press the DO key and enter the following command toUstart the news reader (the example command assumes that "NEWSNODE" is the name of the8nntp machine. Substitute the name of your server node):.literal TPU start_news("NEWSNODE") .end literalK This will get the server connection up, configure everything, and load theGROUPS. file into a buffer. P If you want to automate things a bit more you should define a symbol and createMan init file. Create a file called "NEWS$DIR:EVE$INIT.EVE", and put the lineQ"TPU start__news("NEWSNODE")" (or whatever your news server nodename is) into the?file. Create a symbol (in your login.com for exs~ TNRKIT.BCK(0k"[MIKE.PROJ.NEWSREAD.KIT]DOC.RNO;21U$ &ample) such as:.literal8 READNEWS :== EDIT/TPU/SECTION=NEWS$DIR:NEWS.TPU$SECTION .end literalO(Note: this assumes that the section file is in the NEWS$DIR directory. AdjustNas necessary.) Setting default to NEWS$DIR and typing READNEWS should get youMreading news with no further work. If this is still too much typing you canJcreate a command procedure to change the default directory and execute theNREADNEWS command for you. There are other posibilities for setting up the TPUHinit and section files. See the TPU documentation if you need to use a different method.P To read news once TNR is running, position the cursor to the line with the nameOof the group you want to read and press Control-K. There will be a brief delayMand you will see a list of all available articles for the selected group in abuffer on your screen. .hl 2 Reading articles P To read an article position the cursor to the article and press Control-G. TheMarticle will be loaded into a buffer and you can read it using the normal TPULediting capabilities (page up, page down, arrows, find, etc.). To go to theNnext article you can press Control-K to return to the message list buffer thenPchoose another with Control-G, or just press Control-N to go to the next articleMin the thread or group (TNR will try to follow threads where possible). WhenKyou have read all the articles in the group you are returned to the GROUPS.Lbuffer to choose another group. If you want to return to the GROUPS. bufferPbefore reading all available messages just press Control-K once or twice (if youKare reading a message the first Control-K will take you to the message listNbuffer, the second will take you to the GROUPS. buffer. If you are already in5the message list buffer you only need one Control-K).N If you are reading a message and want to read a message in the "References: "Flist, position the cursor to the message ID you want to read and pressMControl-G. The Control-G will grab the word the cursor is on and use it as aMmessage ID, so be sure the ID is isolated from other IDs, commas, or whateverKbefore you press the Control-G. This function will work for message IDs orNarticle numbers in any buffer, though in the message list buffer the word used#will be the first word on the line.NIf you find an article, or portion of an article, that is ROT-13 encrypted youNcan read the encrypted text very simply. Select the encrypted text (using theHnormal TPU selection mechanism) and press the keypad '5' key (KP5). TheJselected text will be decrypted. If you wish to ROT-13 encrypt some text,Osimply select it and press KP5. ROT-13 is nice in that the same mechanism thatKencrypts plain text, also decrypts coded text. To allow you to reverse theNprocess the selection remains in place after encryption or decryption. If you=want to cancel the selection just press the SELECT key again.I To mark an article as read, delete the line in the message list buffer. OControl-N does this for you automatically, but Control-K and Control-G do not. NThis can be useful if you start to read an article and decide you want to comeMback to it later. Just use Control-K, and move the cursor to another article yourself.7.hl 2 Re-constructing multi-part and uuencoded messagesM There are some newsgroups (such as alt.binaries.pictures) where exchanges ofLbinary pictures (.GIF, .JPG, etc.) are done by uuencoding the picture file. MWhen an encoded file is too long, it is broken up into smaller parts and eachLpart is posted as a seperate article. Usually the subject line will let youJknow the ordering of the parts. The problem is collecting the pieces, andPdecoding the thing back into a binary form. TNR has features to help with this,Obut, alas, due to the many ways of handling such files it can not be made fully automatic.K In TNR the basic idea is to initialize, grab all the pieces, and convert. N Initialization resets counters, deletes any leftover temp files and generallyPgets things ready for grabbing. The init routine is called using the keypad '7'Kkey (KP7). Press it and you will get a message "uu initialized" when it isready.N The next phase is grabbing. You need to grab each part and must do so in theOcorrect order, since as each part is grabbed it is appended to a file. GettingMthings out of order will put the decoded bytes in the wrong order and that isOunlikely to be what you want. To grab a piece, read the message containing thePpart (Control-G or Control-N), then manually trim off any header or trailer infoOthat is not wanted (for uuencoded files everything before the "begin " line andLafter the "end" line). Hint: You can make good use of the LEARN function ifNthere are lots of parts... By the way, you might want to check the file nameJon the "begin " line to make sure it is legal for VMS. It usually is, butOsometimes you will see a full Unix path specification, and this will cause lotsNof problems! It should be pretty easy to find the start and end of the encodedMdata since there is usually a "cut here" line of some sort. (If people wouldOstandardize the cut lines the grab step could be made much more automatic...). POnce you have the message edited, press the keypad '8' key (KP8). After a briefOdelay you will get the message "uu part grabbed." at the bottom of the screen. NThe part has been appended to the end of the growing file and you are ready tograb the next part.J The last phase comes once you have grabbed all the parts that make up theNencoded file. At this point you simply press the keypad '9' key (KP9) and thefile is converted!O The conversion step is simple, but requires some setup on your part. What TNRJdoes is call a command procedure called NEWS$DIR:MULTI__MSG__COMPLETE.COM,Pproviding the name of the appended message file as a parameter. It is up to thePMULTI__MSG__COMPLETE.COM procedure to handle the actual conversion and any otherJactivities (such as moving the decoded file out of the NEWS$DIR directory)Mdesired. It would be nice if this could be standardized as well, but since IMhave no knowledge of what decrypter you might be using, or what you want doneMwith the results, it seemed easiest to just provide this mechanism to let you;set things up the way you like. Just be sure that when theNNEWS$DIR:MULTI__MSG__COMPLETE.COM procedure exits, that you have done what you@need to do, since the appended file will be deleted immediately. .hl 2 Exiting TNRM To exit press Control-Z. You may be asked about saving various buffers. InJgeneral you should reply "Y" to any buffers associated with the GROUPS. or:*.GROUP files, or the TAGS.DAT file and "N" to the others.!.hl 2 Posting replies to articlesQ If you want to post a reply to an article you are reading press Control-P. ThisPwill put you and the article into the post buffer. Your SIGNATURE. (if any) andMa tagline (if any) will be added to the message automatically at this point. MMake whatever changes you like (best to leave the header alone...) then pressLControl-P again to send it. You will have to wait until the news server hasPaccepted the article, so be patient. The return status from the news server willObe shown on the screen when the message post attempt is complete. "200 Article Posted" is what you want to see.*.hl 2 Replying to articles through netmailL If you want to reply to an article through netmail rather than news use theGControl-B key. This works just like the Control-P key. That is, pressNControl-B, edit the reply any way you like, then press Control-B again to sendMit. Reply sends through Pony Express, so if you are using a different mailerHyou may need to change the reply and start__news procedures in NEWS.TPU.+.hl 2 Forwarding an article through netmailQ If you want to forward the article through mail, but not to the author (which isNwhat the Control-B reply command does), use the forward command (Control-F). PWhen you press Control-F you are asked to enter the address of the recipient youNwant to forward the article to. Enter the address as you would if you were in VMS Mail:.literal- ECOVAX::mike .end literalOIf you need to include double quotes (") in your address specification you needPto doubled them (i.e. anywhere you would normally use a double quote, use two ofAthem). For instance to foward an article through Pony Express to"mike@eco.twg.com you should enter:.literal4 PONY%""mike@eco.twg.com"" .end literal2.hl 2 Adding more newsgroups to your configurationO If you want to see what newsgroups are available from your news server, invokeNthe LIST__GROUPS() TPU function, or press Control-J (for "join group"). ThereNwill be a brief delay, then you will be placed into a buffer containing a listJof all available newsgroups. To add a group, place the cursor on the lineMcontaining the name of the group and press Control-J again. The line will beNreplaced by a message saying the group has been added, or one stating that theLgroup was already part of your configuration. The alternative is to use theOCONFIG.COM DCL procedure or create and modify the configuration files with your text editor.2.hl 2 Removing a newsgroup from your configurationK If you want to copmpletely remove a newsgroup from your configuration, useOControl-K to get to the "GROUPS." buffer, and place the cursor on the group youMwant to remove, then invoke the DEL__GROUP() TPU function, or press Control-DN(for "de!lete group"). There may be a brief delay, then you will get a messagePsaying the froup has been removed. The alternative is to use the CONFIG.COM DCLMprocedure or delete and modify the configuration files with your text editor.).hl 1 Have fun!rP That's pretty much it. If you have any questions or suggestions (with code ;-)1you can mail them to mike@eco.twg.com. Have fun!ogong Group (mike@eco.twg.com - 1993)..hl 1 IntroductionITPU-NewsReader (TNR) is a TPU-based Usenet News reader syste0*[MIKE.PROJ.NEWSREAD.KIT]MULTI_MSG_COMPLETE.COM;8+,#T./@ 4NL-0k0123KPWO56>|7Mb|89G@HJN$!****************************************************************************H$! This is a sample of a MULTI_MSG_COMPLETE.COM procedure. It assumes $! several things:$! ,$! o that the input file is a uuencoded file$!I$! o that the command "decode" will execute a uudecode program that takesI$! a command line argument consisting of the name of the file to decode$!F$! o that the logical name "MOVEDEST" points to a directory where you "$! want the decoded file placed.$!K$! You should modify or replace this procedure as necessary for your local$! conditions and needs.$!N$!****************************************************************************$ on error then continue$ open/read file 'p1'$!$LOOP:$ read/end=LOOP_EXIT file line@$ if f$locate("begin", line) .ge. f$length(line) then goto LOOP.$ line = f$edit(line, "compress,trim,upcase")#$ filename = f$element(2," ",line)3$ fname = f$parse(filename,,,"NAME","SYNTAX_ONLY")$! $LOOP_EXIT:$ close/nolog file$ decode 'p1'!$ rename 'filename' movedest:*.*$!$ exit$*[MIKE.PROJ.NEWSREAD.KIT]NEWS.TPU;120+,Z .@/@ 4u@>-0k0123KPWO?56Zח7'89.G@HJ!H! "NEWS.TPU", an EVE-based newsreader originally written by Keith Lewis H! (klewis@mitre.org). This newsreader is pretty simple-minded but very ! easy to use.!L! Additional features, comments and changes have been added by Mike Bartman L! of The Wollongong Group Inc. (mike@eco.twg.com). See the DOC.MEM file for ! details.!J! Other than having EVE on your VAX, the only requirement is a utility to K! connect a process to a news server *SYNCHRONOUSLY*. telnet ... 119 won'tK! work because telnet is asynchronous. The symbol NR should be defined to L! execute this procedure. (A C source file (newsreader.c) is included whichI! will provide this function). Oh, and the news server must support the ! XHDR command.!T! You should use CONFIG.COM to create your initial startup files. The file GROUPS. M! contains a list of the names of the group files. Each group file contains Q! the newsgroup name and the last article known for the group on the first line, O! and one line for each known-but-unread article. CONFIG.COM can also be used S! to add and delete newsgroups from the startup files. Adding newsgroups can also G! be accomplished through the LIST_GROUPS() and ADD_GROUP() procedures.!P! The procedure DEFINE_NEWS_KEYS() is used to customize your newsreading keys. @! Several basic commands are defined in this routine by default.!O! The procedures REPLY, FORWARD_MSG and POST are ordinarily used twice -- once K! to set up the message or article buffer (always quoting old article) and *! once to send the buffer after editing. !G! There is no check for percentage of quoted text or signature length. L! Hopefully folks who tend towards long sigs and/or nothing to say won't be *! able to figure out how to use this. :^)!M! Posting is done while-u-wait, which can take a while, depending on how busy! your server is.! L! Mailing assumes the PONY mailer is in place. You may need to rewrite the H! REPLY and FORWARD_MSG procedures if PONY changes or you are not using ! Wollongong's PONY mailer.!!G! Define some handy keys to simplify calling commonly used procedures.!procedure define_news_keys;@ define_key("get_article", CTRL_G_KEY, "Read this article");@ define_key("next_article", CTRL_N_KEY, "Read next article");A define_key("group", CTRL_K_KEY, "Go to group screen");H define_key("post", CTRL_P_KEY, "Post message to newsgroup");G define_key("reply", CTRL_B_KEY, "Reply to message in mail");M define_key("forward_msg", CTRL_F_KEY, "Forward a message through mail");D define_key("list_groups", CTRL_L_KEY, "List available groups");J define_key("add_group", CTRL_J_KEY, "Subscribe to (join) a group");Q define_key("del_group", CTRL_D_KEY, "Un-Subscribe from (quit) a group"); 9 define_key("init_uu", KP7, "New picture setup");> define_key("grab_uu", KP8, "Grab next picture part");V define_key("complete_uu", KP9, "Done. Save picture and call convert procedure");7 define_key("sort_msgs", KP4, "Sort the buffer");? define_key("trans_rot13", KP5, "Translate ROT-13 string");I define_key ("news_exit", CTRL_Z_KEY, " exit", eve$x_standard_keys); endprocedure;!@! The following procedure is included courtesy of John Whistler! (john_w@mentec.ie).! H!-----------------------------------------------------------------------!>! As the name implies, this is a straightforward bubble-sort=! which will sort the lines in a buffer in ascending order.!=! Optional parameters start_pos, key_length, to specify the?! start position and length of the key to sort on. Default is! position 1 - 40.!H!-----------------------------------------------------------------------!=procedure misc_bubble_sort(;sort_area, start_pos, key_length)3 local swap_flag, saved_pos, line1, line2, line3;$ if sort_area = tpu$k_unspecified then$ sort_area := current_buffer; endif;$ if start_pos = tpu$k_u nspecified then start_pos := 1; endif;% if key_length = tpu$k_unspecified then key_length := 40; endif; saved_pos := mark(none); loop# position(beginning_of(sort_area)); swap_flag := 0; line1 := current_line; loop move_vertical(1);- exitif (mark(none) = end_of(sort_area)); line2 := current_line;- if substr(line1,start_pos,key_length) > 1 substr(line2,start_pos,key_length) then line3 := erase_line; move_vertical(-1); copy_text(line3); split_line; swap_flag := 1; else line1 := line2; endif; endloop; exitif swap_flag = 0; endloop; position(saved_pos); endprocedure;!I! Sort the text in the current buffer. Use the TPU bubble sort if it isH! a short buffer. Spawn a DCL process to do it if it is a long buffer.!procedure tpu$sort_buffer;" local num_lines, SortProc_Buffer;: num_lines := GET_INFO(current_buffer, "record_count");! if( num_lines < 50 ) then 0 misc_bubble_sort(current_buffer, 7, 70); else8 SortProc_Buffer := create_buffer("Sort_Buffer");g Sort_process := create_process(SortProc_Buffer, "$ DELETE/NOLOG/NOCONFIRM NEWS$DIR:tnr_temp.sort;*");= write_file(current_buffer, "NEWS$DIR:tnr_temp.sort");a send("$ sort/key=(pos:8,size:50) NEWS$DIR:tnr_temp.sort NEWS$DIR:tnr_temp.sort", Sort_process); erase(current_buffer);, read_file("NEWS$DIR:tnr_temp.sort");: send("$ delete NEWS$DIR:tnr_temp.sort;*", Sort_process); send_eof(Sort_process); delete(SortProc_Buffer); endif;+ position(beginning_of(current_buffer)); endprocedure;!E! Sort the messages in the buffer. Use the TPU bubble sort if it isH! a short buffer. Spawn a DCL process to do it if it is a long buffer.!procedure sort_msgs;8 local first_line, num_lines, SortProc_Buffer, sort_pos;+ position(beginning_of(current_buffer)); first_line := erase_line; : num_lines := GET_INFO(current_buffer, "record_count");!F! Fix up lines some. Subjects starting with "RE:" cause problems, soD! we add spaces to the start of non-RE: lines to get them to group ! properly.! loop. exitif (mark(none) = end_of(current_buffer));^ if( search_quietly(" Re: ", forward, no_exact, create_range(line_begin, line_end)) = 0 ) then, position(search_quietly(" ", FORWARD)); copy_text(" "); else, position(search_quietly(" ", FORWARD)); endif; move_vertical(1);. exitif (mark(none) = end_of(current_buffer));6 position(search_quietly(line_begin, reverse)); endloop;!! Do the actual sort!+ position(beginning_of(current_buffer));+ position(search_quietly(" ", forward));' sort_pos := current_offset + 5; ! if( num_lines < 50 ) then 7 misc_bubble_sort(current_buffer, sort_pos, 50); else8 SortProc_Buffer := create_buffer("Sort_Buffer");g Sort_process := create_process(SortProc_Buffer, "$ DELETE/NOLOG/NOCONFIRM NEWS$DIR:tnr_temp.sort;*");= write_file(current_buffer, "NEWS$DIR:tnr_temp.sort");u send("$ sort/key=(pos:" + str(sort_pos) + ",size:50) NEWS$DIR:tnr_temp.sort NEWS$DIR:tnr_temp.sort", Sort_process); erase(current_buffer);, read_file("NEWS$DIR:tnr_temp.sort");: send("$ delete NEWS$DIR:tnr_temp.sort;*", Sort_process); send_eof(Sort_process); delete(SortProc_Buffer); endif;+ position(beginning_of(current_buffer)); copy_text(first_line); split_line; endprocedure;!K! trans_rot13() is a procedure for translating ROT-13 encoded strings intoG! clear text. When invoked, trans_rot13() will translate the selectedM! text in place (use the select key and move the cursor to select the text).!procedure trans_rot13;, local RotRange, CharString, TransString;J CharString := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";J TransString := "NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm"; RotRange := SELECT_RANGE; message( "Working...");A TRANSLATE( RotRange, TransString, CharString, IN_PLACE ); ' message( "Translation complete." ); endprocedure;!L! The init_uu() procedure sets things up to capture and decode a multi-partH! message (typically uuencoded). Invoke this prior to saving the first! part with grab_uu().!procedure init_uu; part_counter := 0;7 if get_info(DCL_process, "type") = "UNDEFINED" thenA DCL_process := create_process(DCL_Buffer, "$ SHOW TIME"); endif;J send("$ delete/nolog/noconfirm NEWS$DIR:NEWSFOOUU*.*;*", DCL_process); message( "uu initialized."); endprocedure;!G! The grab_uu() procedure saves the current buffer to a temporary fileD! and bumps the part counter. This procedure should be called onceF! for each message part. Perform any editing of the buffer (removingD! headers or trailers or whatever) prior to calling this procedure.!procedure grab_uu;% part_counter := part_counter + 1;0 newfile := "NEWSFOOUU." + str(part_counter);) write_file(newsread_buffer, newfile);D send("$ append/new " + newfile + " NEWSFOOUU.BAR", DCL_process);" message( "uu part grabbed." ); endprocedure;!R! The complete_uu() procedure is used to assemble and decode a multipart message.Q! It is called once all of the constituent parts have been saved with grab_uu().N! This procedure invokes a procedure called news$dir:multi_msg_complete.com, H! and passes it a single parameter: the name of the file containing theN! reassembled parts of the message. The invoked procedure is responsible forR! performing any processing required to complete handling of the message (runningM! uudecode, renaming files, moving or deleteing files, etc.). complete_uu()R! finishes up by deleting the temporary files created by init_uu() and grab_uu().!procedure complete_uu;K send("$ @news$dir:multi_msg_complete.com NEWSFOOUU.BAR", DCL_process);7 if get_info(DCL_process, "type") = "UNDEFINED" then` message( "The DCL process seems to have died. The conversion may not have completed."); return; endif;J send("$ delete/nolog/noconfirm NEWS$DIR:NEWSFOOUU*.*;*", DCL_process);7 if get_info(DCL_process, "type") = "UNDEFINED" then` message( "The DCL process seems to have died. The conversion may not have completed."); return; endif; message( "uu converted." ); endprocedure;procedure start_news(newshost);4 newsread_buffer := create_buffer("News Reader");' set(no_write, newsread_buffer, ON);D newsread_process := create_process(newsread_buffer, "hostname");; hostname := str(newsread_buffer) - "" + ".eco.twg.com";Z send("set proc/name='f$edit(f$getj(0, ""username""), ""trim"")'_n", newsread_process); erase(newsread_buffer);I send("write sys$output f$getjpi(0, ""username"")", newsread_process);( change_case(newsread_buffer, lower);1 username := edit(str(newsread_buffer), TRIM); erase(newsread_buffer);# send("mail", newsread_process);' send("sho pers", newsread_process);# send("exit", newsread_process);, position(beginning_of(newsread_buffer));? split := search_quietly("Your personal name is ", forward); position(split); erase(split); eve_erase_line;; fullname := substr(str(eve$x_restore_line), 2) - """."; erase(newsread_buffer);/ send("$ nr " + newshost, newsread_process); define_news_keys;, position(beginning_of(newsread_buffer));3 status := search_quietly("try later", forward); if status <> 0 then8 message(" News reader busy. Try again later."); return; endif;, eve_get_file("NEWS$DIR:NEWSREAD.REPLY");6 reply_buffer := eve$find_buffer("NEWSREAD.REPLY");( set(right_margin, reply_buffer, 76);& eve_get_file("NEWS$DIR:TAGS.DAT");. tag_buffer := eve$find_buffer("TAGS.DAT");4 mailer_buffer := create_buffer("Mailer buffer");) set(right_margin, mailer_buffer, 76);, set(right_margin_action, mailer_buffer, 6 get_info(current_buffer, "right_margin_action"));% set(no_write, mailer_buffer, ON);0 post_buffer := create_buffer("Post buffer");' set(right_margin, post_buffer, 76);* set(right_margin_action, post_buffer, 6 get_info(current_buffer, "right_margin_action"));. DCL_Buffer := create_buffer("DCL_Buffer");" set(no_write, DCL_Buffer, ON); erase(DCL_Buffer);= DCL_process := create_process(DCL_Buffer, "$ SHOW TIME"); eve_get_file("GROUPS.");0 groups_buffer := eve$find_buffer("GROUPS."); endprocedure;procedure add_tagline;!G! This procedure adds the next tagline from the taglines buffer to theH! current message. If the taglines buffer doesn't exist, it is createdI! and filled feom the file NEWS$DIR:TAG.DAT. If you are not creating a M! message, or if the TAG.DAT file isn't found, the procedure does nothing. K! The current tag is the one at the beginning of the buffer. Once the tagJ! has been obtained, the line is moved to the bottom of the tag buffer. .! Each tag is assumed to be exactly one line.!, if (current_buffer <> post_buffer) then  return; endif;= if get_info(BUFFER, "find_buffer", "tag_buffer") = 0 then' dummy := FILE_SEARCH (''); 6 if FILE_SEARCH("NEWS$DIR:TAGS.DAT") = "" then return; endif;# eve_get_file("NEWS$DIR:TAGS.DAT");2 tag_buffer := eve$find_buffer("TAGS.DAT"); endif;' position(beginning_of(tag_buffer)); tagln := erase_line;) position(end_of(tag_buffer));  copy_text(tagln);% position(end_of(post_buffer)); ` copy_text("=============================================================================="); split_line; copy_text(tagln);= fill(create_range(line_begin, line_end), " ", 1, 76, 0); split_line;` copy_text("------------------------------------------------------------------------------"); split_line;( position(beginning_of(post_buffer));% map(current_window, post_buffer); endprocedure;procedure list_groups;!E! This procedure will open a buffer and place a list of all availableI! newsgroups in it. You may then use add_group() to add the group on the&! line where the cursor is positioned.!---J! Check to see if we already have a list buffer. If so, make it current.H! If not, create the buffer and query the news server for the available5! groups and make the new buffer the current buffer.!. if current_buffer <> grouplist_buffer thenH if get_info(BUFFERS, "find_buffer", "grouplist_buffer") = 0 then= grouplist_buffer := create_buffer("groups_list");) set(no_write, grouplist_buffer, ON);# erase(newsread_buffer);2 send("LIST ACTIVE", newsread_process);5 position (beginning_of(newsread_buffer));6 position (beginning_of(grouplist_buffer));' copy_text(newsread_buffer);6 position (beginning_of(grouplist_buffer)); endif;. map(current_window, grouplist_buffer);S set(status_line, current_window, reverse, "List of available newsgroups."); endif;2 position(search_quietly(line_begin, reverse)); endprocedure;procedure add_group;J! This procedure will add the group named at the beginning of the currentM! line of the current buffer. Intended to be used following a list_groups()! procedure call.!---L! See if we already have this group. File name for the group is the group K! name with "." changed to "_" and ".group" appended. If the group is notL! already one of ours, add it and replace the group name in the buffer withK! the words "". If it is already subscribed then replace the=! groupname with the words "".!. if current_buffer <> grouplist_buffer then list_groups(); return; endif;2 position(search_quietly(line_begin, reverse));) groupname := str(eve$current_wor!d());. groupname := edit(groupname, TRIM, LOWER);2 position(search_quietly(line_begin, reverse)); eve_erase_line;y[ if (groupname = "") or (groupname = "") thene return;k endif;K shortname := translate(groupname, "_", ".", NOT_IN_PLACE) + ".group"; ( filename := "NEWS$DIR:" + shortname; dummy := FILE_SEARCH ('');s& if FILE_SEARCH(filename) = "" then- groupbuff := create_buffer(filename);o# position(beginning_of(groupbuff));r copy_text(groupname + " 0"); ! write_file(groupbuff, filename);u delete(groupbuff); ) groupbuff := eve$find_buffer("GROUPS.");o position(end_of(groupbuff));h copy_text(shortname);+ write_file(groupbuff, "NEWS$DIR:GROUPS.");u position(grouplist_buffer); copy_text(""); split_line;s else- copy_text("");  split_line;s endif; endprocedure;iM! This procedure will delete the group named at the beginning of the currenteL! line of the current buffer. Intended to be used from the GROUPS. buffer.!---S! If the current buffer is not the GROUPS. buffer, just return and put up an errorPW! message. If it is the right buffer, check to see if the group file exists. If not,mT! put up and error and quit. IF all looks good, kill the group file and delete the&! group name from the GROUPS. buffer.!Rprocedure del_group;+ if current_buffer <> groups_buffer then L message(" You need to be at the GROUPS. buffer to delete a group."); return; endif;2 position(search_quietly(line_begin, reverse));* groupfname := str(eve$current_word());0 fullfname := edit(groupfname, TRIM, LOWER);* fullfname := "NEWS$DIR:" + fullfname; dummy := FILE_SEARCH ('');d' if FILE_SEARCH(fullfname) = "" then 8 message(" The group doesn't seem to exist. Quiting."); copy_text(groupfname);s return; endif; erase_line; F send("$ delete/nolog/noconfirm " + fullfname + ";*",% DCL_process);, message(" The group has been removed."); endprocedure;nprocedure get_article;!mD! This procedure will retrieve an article into the newsreader bufferJ! The first word on the current line of the current buffer is taken as theM! article number (or message-ID) if the current buffer is the msglist_buffer._L! If the current buffer is *not* the msglist_buffer then the current word isN! assumed to be a valid article number (or message-ID). This allows retrieval6! of messages from entries in the "References: " line.!_ local art_num;+ if current_buffer = msglist_buffer thenp6 position(search_quietly(line_begin, reverse)); endif;' art_num := str(eve$current_word());  erase(newsread_buffer);_3 send(("ARTICLE " + art_num), newsread_process);o) map(CURRENT_WINDOW, newsread_buffer);7F set(status_line, current_window, reverse, " Article " + art_num +  " from " + group_name);- position (beginning_of(newsread_buffer));d4 position (S~ TNRKIT.BCKZ 0k$[MIKE.PROJ.NEWSREAD.KIT]NEWS.TPU;120u@]'search_quietly("Subject: ", forward)); eve$current_word();r= subject := create_range(mark(none), line_end, underline);i- position (beginning_of(newsread_buffer));E endprocedure;$!aE! This procedure's behavior depends on the current buffer. If we aredL! in the groups_buffer it will fetch a group file and retrieve subject linesO! of recent articles. If we are in the msglist_buffer or the group_list buffereO! it will put us in the groups_buffer. If we are anywhere else it will put us e! in the msglist_buffer.! procedure group;5 local file_name, last_known, last_now, group_str;o if (msglist_buffer = 0) or t- (current_buffer = grouplist_buffer) or-- (current_buffer = msglist_buffer) then-+ map(current_window, groups_buffer);l6 position(search_quietly(line_begin, reverse));, eve$set_status_line(current_window); return; endif;- if (current_buffer <> groups_buffer) thenc, map(current_window, msglist_buffer);/ positio)n(search_quietly(line_begin, reverse)); % eve$set_status_line(current_window);  return; endif;!h@! If we get here then we were in the groups buffer and the user/! wants to read the group on the current line._!a2 position(search_quietly(line_begin, reverse));) file_name := str(eve$current_word());m1 msglist_buffer := eve$find_buffer(file_name);r if msglist_buffer = 0 then eve_get_file(file_name);) msglist_buffer := current_buffer; else, map(current_window, msglist_buffer); endif;+ position(beginning_of(msglist_buffer));10 group_name := str(eve$current_word()) - " ";* last_known := str(eve$current_word()); erase(newsread_buffer);;' group_str := "GROUP " + group_name;e& send(group_str, newsread_process);, position(beginning_of(newsread_buffer)); eve$current_word;t eve$current_word;./ first_now := str(eve$current_word()) - " ";n. last_now := str(eve$current_word()) - " "; + if int(last_known) < int(last_now) thene) if int(last_known) < int(first_now) thent+ last_known := str(int(first_now) - 1);o endif;f erase(newsread_buffer);"G send("XHDR subject " + str(int(last_known)+1) + "-" + last_now,O newsread_process); / position(beginning_of(msglist_buffer));. eve$current_word;y eve_erase_word;: copy_text(last_now);) position(end_of(msglist_buffer));r# copy_text(newsread_buffer);$ endif;+ position(beginning_of(msglist_buffer));s move_vertical(1);/ if mark(none) = end_of(msglist_buffer) then_ show_groups; endif; endprocedure;u!_H!This procedure erases the current line in the group buffer (presumably G!referring to the article in the newsread buffer) and goes to the next s!logical article. !oprocedure next_article; local next_art, new_subject; on_error( if error = tpu$_strnotfound then new_subject := 1;  endif; endo-n_error;( map(CURRENT_WINDOW, msglist_buffer); position(msglist_buffer);o/ if mark(none) = end_of(current_buffer) then 5 if get_info(current_buffer, "modified") then e' write_file(current_buffer);o endif; show_groups; return;( endif; eve_erase_previous_word; new_subject := 0;i4 next_art := search_quietly(erase_line, forward); if next_art <> 0 then_ position(next_art);p else position(BUFFER_BEGIN);d move_vertical(1);e endif;0 if mark(none) <> end_of(current_buffer) then get_article;A if (search_quietly("423 Bad article number", forward) <> 0) then  next_article; endif;_ else# write_file(current_buffer);r show_groups; endif; endprocedure;procedure show_groups; on_error; ( if error = tpu$_strnotfound then endif; endon_error;' map(current_window, groups_buffer);;2 position(search_quietly(line_begin, forward));( eve$set_status_line(current_window); endprocedure; procedure news_exit; send_eof(newsread_process);) if( DCL_process <> 0 ) thent send_eof(DCL_process); endif;, position(beginning_of(newsread_buffer));> if get_info(BUFFER, "find_buffer", "tag_buffer") <> 0 then write_file(tag_buffer);e delete(tag_buffer);o endif;= if get_info(BUFFER, "find_buffer", "groupbuff") <> 0 then  write_file(groupbuff); delete(groupbuff); endif;? if get_info(BUFFER, "find_buffer", "post_buffer") <> 0 thent delete(post_buffer); endif;A if get_info(BUFFER, "find_buffer", "mailer_buffer") <> 0 then  delete(mailer_buffer); endif;D if get_info(BUFFER, "find_buffer", "grouplist_buffer") <> 0 then! delete(grouplist_buffer);o endif; eve_exit;r endprocedure;rprocedure post;J. local message_id, author_name, references;( if current_buffer = post_buffer then( ! He kno1ws what he wants to post' send("post", newsread_process);n, send(post_buffer, newsread_process);$ send(".", newsread_process);- map(current_window, newsread_buffer);e( set(modified, post_buffer, off);C set(status_line, current_window, reverse, " Post results");  else. if current_buffer = newsread_buffer then' ! So he wants to post something; erase(post_buffer);  message_id := "";y references := "";  author_name := "";) map(current_window, post_buffer);n2 set(status_line, current_window, reverse, 4 " Followup from article in " + group_name);# copy_text(newsread_buffer);e, position(beginning_of(post_buffer));@ copy_text("From: " + username + "@" + hostname + " (" +  fullname + ")");  split_line;t loop, word := str(eve$current_word()); exitif word = "";o% change_case(word, LOWER); # if word = "from: " thenu( eve_erase_previous_word;* author_name := erase_line; else* if word = "message-id: " then6 message_id := str(eve$current_word()); erase_line; else)+ if word = "references: " thenu( eve_erase_previous_word;. references := str(erase_line); elseF if (word = "subject: ") or (word = "newsgroups: ") then* if (word = "subject: ") * 8 (substr(str(subject), 1, 3) <> "Re:") *; (substr(str(subject), 1, 3) <> "RE:") thenm& copy_text("Re: "); endif;> position(search_quietly(line_begin, forward)); else( erase_line;g endif;e endif; endif;d endif; endloop; move_vertical(-1);H copy_text("References: " + " " +5 references + " " + message_id);B fill(create_range(line_begin, line_end), " ", 5, 80, -4); split_line;  move_vertical(1); P copy_text("In article " + message_id + ", " + author_name + " writes:"); split_line;g loop7 exitif mark(none) = end_of(current_buffer);  copy_text(">");d move_horizontal(-1); move_vertical(1);  endloop; split_line;)) read_file("NEWS$DIR:SIGNATURE.");s split_line; add_tagline();e else1 message(" This buffer is not postable.");b endif; endif; endprocedure;aprocedure reply;: local message_id, author_name, references, text_begin;) if current_buffer = reply_buffer thenmJ ! He knows what he wants to say (buffer is set from previous call)! write_file(reply_buffer);r@ mailer_process := create_process(mailer_buffer, "$ SHOW TIME");R send("$ mail NEWS$DIR:NEWSREAD.REPLY """ + recipientaddr + """", mailer_process);L send("$ delete/nolog/noconfirm NEWS$DIR:NEWSREAD.REPLY;*", mailer_process); send_eof(mailer_process);- map(current_window, newsread_buffer);, eve$set_status_line(current_window); else. if current_buffer = newsread_buffer then ! So he wants to reply erase(reply_buffer); message_id := "";  author_name := ""; references := "";(* map(current_window, reply_buffer);# copy_text(newsread_buffer);n- position(beginning_of(reply_buffer));b split_line;:B copy_text("From: " + username + " """ + fullname + " fao(""" !%D", 0)); split_line; loop, word := str(eve$current_word()); exitif word = "";$% change_case(word, LOWER);(# if word = "from: " then ( eve_erase_previous_word;* author_name := erase_line;" loc := index(author_name, " (");L recipientaddr := "PONY%""""" + substr(author_name, 1, loc) - " " + """"""; else* if word = "message-id: " then6 message_id := str(eve$current_word()); erase_line;t elsee+ if word = "references: " then( eve_erase_previous_word;. references := str(erase_line); else+ if (word = "subject: ") thene( eve_erase_previous_word;$ copy_text("Subj: ");> position(search_quietly(line_begin, forward)); else  erase_line;; endif;r endif; endif;  endif; endloop;! text_begin := mark(none); - position(beginning_of(reply_buffer));e move_vertical(2);e( copy_text("To: " + author_name); split_line;e position(text_begin);f move_vertical(-1);B copy_text("References: " + message_id + " " + references); split_line;  move_vertical(1);e? copy_text("In article " + message_id + ", you write:");d split_line;n loop7 exitif mark(none) = end_of(current_buffer);i copy_text(">");f move_horizontal(-1); move_vertical(1);H endloop; split_line;E( read_file("NEWS$DIR:signature"); else2 message(" This buffer is not replyable."); endif; endif; endprocedure; !;#! Forward the posting thru mail. r!procedure forward_msg;* local Recip, MailAddr, Subjtext, Temp;. if current_buffer = newsread_buffer then erase(reply_buffer);o* map(current_window, reply_buffer);# copy_text(newsread_buffer);=- position(beginning_of(reply_buffer));) Subjtext := "";b7 position(search_quietly("Subject: ", forward));  Temp := erase_line; copy_text(Temp);- split_line;-6 position(search_quietly(line_begin, reverse)); mov=e_vertical(-1);t eve_erase_word;& copy_text(group_name + "-> ");6 position(search_quietly(line_begin, reverse)); Subjtext := erase_line;i copy_text(Temp); split_line;< Recipaddr := read_line("Recipient's address: ", 80);/ MailAddr := "PONY%""""" + Recipaddr + """""";C ! write_file(reply_buffer); @ mailer_process := create_process(mailer_buffer, "$ SHOW TIME");o send("$ mail/subject=""" + str(Subjtext) + """ NEWS$DIR:NEWSREAD.REPLY """ + MailAddr + """", mailer_process);ob message("$ mail/subject=""" + str(Subjtext) + """ NEWS$DIR:NEWSREAD.REPLY """ + MailAddr + """");L send("$ delete/nolog/noconfirm NEWS$DIR:NEWSREAD.REPLY;*", mailer_process); send_eof(mailer_process);- map(current_window, newsread_buffer);e, eve$set_status_line(current_window); else4 message(" This buffer is not forwardable."); endif; endprocedure;f%*[MIKE.PROJ.NEWSREAD.KIT]NEWSREAD.C;32+,? ./@ 4Sf-0k0123KPWO56<|7=|89G@HJ/*L * This is a bare-bones synchronous newsreader. It takes a single argument,O * which is the hostname of the news server. Most of it was hacked out of rrn,I * with minor modifications by Keith Lewis to run under WIN/TCP on a VAX. *H * Some harmless (I hope) reformating was done by Michael Bartman of the * Wollongong Group, Inc., 1993. * */#define size_t size_t_aux#define DEF_PORT 119#include #include #include #include #include #include #include #include #include #include "int server_init( char *machine );)int get_server( char *string, int size );int getsocket( char *machine );/*B * put_server -- send a line of text to the server, terminating it( * with CR and LF, as per ARPA standard. *7 * Parameters: "string" is the string to be sent to the * server. * * Returns: Nothing. *% * Side effects: Talks to the server. * */ int ser_rd; int ser_wr;void put_server( char *string ){ char ser_line[258]; #ifdef DEBUG( fprintf(stderr, ">>> %s\n", string);#endif( sprintf( ser_line, "%s\n", string );3 netwrite( ser_wr, ser_line, strlen(ser_line) );} /* end put_server *//*D * close_server -- close the connection to the server, after sending * the "quit" command. * * Parameters: None. * * Returns: Nothing. *7 * Side effects: Closes the connection with the server./ * You can't use "put_server" or "get_server"" * after this routine is called. */void close_server(){ char ser_line[256]; put_server( "QUIT" );4 (void) get_server( ser_line, sizeof(ser_line) ); (void) close( ser_wr ); (void) close( ser_rd );} /* end close_server */main( int argc, char *argv[] ){ char *a; char line[135]; int ia; for( ia = 1;3 ((argv[ia] != 0) && (*(argv[ia]) == '-')); ia++ ) { } /* end for all options */ if (argv[ia] == 0)  { a = ""; } else { a = argv[ia];% } /* end if no server name arg */ server_init( a );/ if( get_server( line, sizeof(line) ) < 0 )  { puts( line ); exit( 1 );' } /* end if error on server read */ puts( line ); while( !feof(stdin) ) { gets( line );' if( strcmp(line, "QUIT") == 0 ) {" (void) close_server(); exit( 1 ); } /* end if QUIT time */7 if( line[0] != 0 ) /* just skip null strings */ { 2 put_server( line ); /* send command */@ get_server( line, sizeof(line) ); /* get response */2 if( line[0] == '3' ) /* continue... */ { 1 while( strcmp( line, "." ) != 0 ) {! gets( line );' put_server( line );8 } /* end while not at end of xmission */1 get_server( line, sizeof(line) ); puts( line ); } / else if( (ia = atoi(line)) == 205 ) {' (void) close( ser_wr );' (void) close( ser_rd ); exit( 1 ); }B else if( (line[0] > '2') | (ia == 223) | (ia == 211) ) { puts( line ); } else  {A while( (get_server( line, sizeof(line) ) >= 0) &&& !((line[0] == '.') &&7 ((line[1] == 13) || (line[1] == 0))))  {! puts( line );! } /* end while */" } /* end if line[0] is '3' */# } /* end if line[0] != 0 */ } /* end if !feof(stdin) */ (void) close_server();} /* end main *//*; * server_init Get a connection to the remote news server. *6 * Parameters: "machine" is the machine to connect to. *% * Returns: -1 on error, 0 otherwise. *$ * Side effects: Connects to server. */!int server_init( char *machine ){ int sockt_rd, sockt_wr; char line[256];> sockt_rd = getsocket( machine ); /* Get a socket to the */0 if( sockt_rd < 0 ) /* server, abort on */ { return( -1 ); } /* end if sokt_rd < 0 *//*; * Now we'll make file pointers (i.e., buffered I/O) out of7 * the socket file descriptor. Note that we can't just7 * open a fp for reading and writing -- we have to open: * up two separate fp's, one for reading, one for writing. */ ser_rd = sockt_rd; ser_wr = sockt_rd;} /* end server_init *//*= * getsocket -- get us a socket connected to the news server. *A * Parameters: "machine" is the machine the server is running on. *2 * Returns: Socket connected to the news server if! * all is ok, else -1 on error. *$ * Side effects: Connects to server. * * Errors: Printed via perror. */int getsocket( char *machine ){ int s; struct sockaddr_in sin;( struct servent *getservbyname(), *sp;( struct hostent *gethostbyname(), *hp; short int portnum; int success = 0; int addr_ind; extern errno;8 if( (sp = getservbyname( "nntp", "tcp") ) == NULL ) { portnum = htons(DEF_PORT);S fprintf( stderr, "nntp/tcp: Unknown service...using default of %d.\n", DEF_PORT ); } else { portnum = sp->s_port;% } /* end if got server by name */1 if( (hp = gethostbyname( machine )) == NULL ) {3 fprintf( stderr, "%s: Unknown host.\n", machine ); return( -1 );* } /* end if didn't get host by name */ for( addr_ind = 0; 2 (hp->h_addr_list[addr_ind] != 0) && (!success);  addr_ind++ ) {) memset( (char *) &sin, 0, sizeof(sin) );L memmove( (char *) &sin.sin_addr, hp->h_addr_list[addr_ind], hp->h_length );! sin.sin_family = hp->h_addrtype; sin.sin_port = portnum; G if( (s = socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) /* Get the socket */ {  perror( "socket" ); return( -1 );! } /* end if didn't get socket *//* * And then connect */> if( connect( s, (struct sockaddr *) &sin, sizeof(sin) ) < 0 ) {$ if( errno != ETIMEDOUT ) { perror( "connect" ); return( -1 );! } /* end if not a timeout */ } else { success = -1; } /* end if no connect */ } /* end for each address */  if( success ) { return( s ); } else { return( -1 ); } /* end if success */} /* end getsocket *//*< * get_server -- get a line of text from the server. Strips * CR's and LF's. *4 * Parameters: "string" has the buffer space for the * line received.& * "size" is the size of the buffer. *% * Returns: -1 on error, 0 otherwise. *? * Side effects: Talks to server, changes contents of "string". */" static char buffer[256] = {'\0'}; static char *bp = buffer; (int get_server( char *string, int size ){ register char *cp; char *index();+ while( (cp = index(bp, '\n')) == NULL ) { int bytes_read; strcpy( string, bp ); string += strlen(string);< bytes_read = netread( ser_rd, buffer, sizeof(buffer) - 2 ); buffer[bytes_read] = '\0'; if( buffer[0] == '\0') { return( -1 ); } /* end if buffer not empty */ bp = buffer; } /* end while */ *cp = '\0'; strcpy( string, bp ); bp = cp+1;, if( (cp = index(string, '\r')) != NULL ) { *cp = '\0'; }1 else if( (cp = index(string, '\n')) != NULL ) { *cp = '\0'; } /* end if not a \r */$ for( cp = string+strlen(string); cp >= string;  cp-- ) {  if( *cp == '\r' ) { *cp = '\0'; } /* end if found \r */ } /* end for each string */ #ifdef DEBUG* fprintf( stderr, "<<< %s\n", string );#endif return( 0 );} /* end get_server */&*[MIKE.PROJ.NEWSREAD.KIT]NEWSREAD.EXE;1+,./@ 4 -0k0123 KPWO 56(yG}7NG}89G@HJ0D`0205iG} hNEWSREADV1.0iG}05-13  ?! TWGLIB_001 ! VAXCRTL_001$+CMA$TIS_SHR_001E!d FORRTL_001! LIBRTL_001Q! MTHRTL_001!h SMGSHR_001%s QUITQUIT.nntptcpnntp/tcp: Unknown service...using default of %d. %s: Unknown host. socketconnectp^ݬerPD^Rߢߢ%2P<~h^IR[SެQCP`-TSCd CP`-޼UCeޢ TCeTT~u@PuU`uAoP`S 1%Z>V/nY-XWTUujߢ ufP u1FubsishPskg~udu3\ߢufP6PujubqiqhPqkgߢufP̚~udue1Pu9PSSk 1Pu2PPQPSPPQPSPPQ uePP~udP>u. v 0v*ue~udPu.v vP`P 1}&2P^ݬPPP:P7P^TZXVߤߤPR%w~PWw~ߤ.WݬPRݬߤLPSC1VPݢ CW[PUߤ_tPU>Ph<ߤfOPVSCVVUPP|^V T PRSPЬSSSSP~df@ddPd PRbЬSSR SXPRbP SAP`ެScUU{UPPUP` `PPcP@@Px |D40 ,  @TWGLIBVAXCRTL CMA$TIS_SHRFORRTLLIBRTLMTHRTLSMGSHRNEWSREAD put_server<< close_serverh mainx server_init&D getsocketT get_server  &*[MIKE.PROJ.NEWSREAD.KIT]NEWSREAD.OBJ;1+,)./@ 4 -0k0123KPWO56DF}7Wd.G}89G@HJ5NEWSREADV1.0 4-JAN-1995 17:01VAX C V3.2-044 P%s  PQUIT PQUIT P. Pnntp Ptcp Pnntp/tcp: Unknown service...using default of %d.  LP%s: Unknown host.  _Psocket fPconnectPP^ݬ SPRINTFSTRLENP NETWRITE^ RߢߢSPRINTFSTRLENP NETWRITE<~ GET_SERVER CLOSECLOSEh^ C$MAIN_ARGS R [SެQCP`-TSCd CP`-޼UCeޢ TCeTT SERVER_INIT~u GET_SERVERPuPUTSEXITuPUTSP`S 1GETSZSTRCMPVEXITnSPRINTFYSTRLENXNETWRITEW GET_SERVERTPUTSUCLOSEujߢ ufP CLOSE_SERVERu1FubsishPskg~udu3\ߢufP6PujubqiqhPqkgߢufP̚~udue1PuATOIPSSk1Pu2PPQPSPPQPSPPQ uePP~udP>u. v 0v*ue~udPu.v vP`P 1} CLOSE_SERVER2P^ݬ GETSOCKETPPPP P^ TXVߤߤ GETSERVBYNAMEPR%w~HTONSPWw~ߤFPRINTFWݬ GETHOSTBYNAMEPRݬߤLFPRINTFPSC1VPMEMSETݢ CMEMMOVEWSOCKETPUߤ_PERRORPUCONNECTPh<ߤfPERRORPVSCVVUPP|^V C$V_CTYPEDEFS CLOSE_SERVER PUT_SERVER GETSOCKET GET_SERVER SERVER_INITHTONSCONNECTSOCKETCLOSEMEMSETMEMMOVESTRLENSTRCMPSTRCPYEXITATOIPERRORSPRINTFFPRINTFPUTSGETSNETWRITE GETHOSTBYNAME GETSERVBYNAMENETREADINDEX PUT_SERVER < CLOSE_SERVER MAIN  SERVER_INIT D GETSOCKET T| GET_SERVERRNEWSREAD put_server<< close_serverh mainx server_init&D getsocketT get_server   C$MAIN_ARGS9$CODE$DATASTDINSTDOUTSTDERR_CTYPE_ERRNO VAXC$ERRNOSER_RDSER_WRn$CHAR_STRING_CONSTANTST INDEXPRSPЬSSSTRCPYSSTRLENSP~dfNETREAD@ddPd INDEXPRbЬSSSTRCPYR SINDEXPRbP SINDEXP`ެScUUSTRLENUPPUP` `PPcP$*[MIKE.PROJ.NEWSREAD.KIT]SIGNATURE.;3+,X ./@ 4N -0k0123KPWO566!cp7 $'89.G@HJN==============================================================================N| This is a "SIGNATURE." file template. The contents of this file will be |N| appended to every message created for posting to a newsgroup or mailing |N| through PONY. Edit this file in any way you desire, or delete it if you |N| do not want to use the signature feature. |N| |N| -- Michael Bartman |N| The Wollongong Group, Inc. |N| |N=============================================================================="*[MIKE.PROJ.NEWSREAD.KIT]TAGS.DAT;4+,L./@ 4H-0k0123KPWO56v6Jp7h"-'89.G@HJ# Is this thing on?0-------- The information went data way -------->A)bort R)etry D)etonate?>All I ask is a chance to prove that money can't buy happiness.+All wiyht. Rho sritched mg kegtops awound?-Apathy Error: Don't bother striking any key.2Backup not found: A)bort, R)etry, C)ardiac arrest?.Budget: A method for going broke methodically."Cleanliness is next to impossible.4Despite the high cost of living, it remains popular.!A)bort, R)etry, I)gnore, V)alium?8I went to the Net and all I got was this stupid tagline.My computer NEVER cras,My mail reader can beat up your mail reader.My other tagline is a footnote.4To define recursion, we must first define recursion.@Process discontinued. Enter any 12-digit prime number to resume.+"Daddy, what does FORMATTING DRIVE C mean?"H------------------Scratch here to reveal your prize---> ##############E2 rules to success in life. 1. Don't tell people everything you know.2Click...click...click...darn, out of new taglines.ly:0k"[MIKE.PROJ.NEWSREAD.KIT]IEZ;5]1-FM BpH2#pho{/a bpmdfJ$4q+&gVh0>#w| ZL+ 8v#\Kow'z:kw O$ Z8`?S.C#d jb19nIQjxRG%`xo=dco?0$=G9nGR_0v*(9fx8yyrj3$?cg-T& $}+*& W/z;*7%k/o"p1P1S@V0@*aai+W 4@W]i}jhXv.Czg;n/OjThpHQ1*%c~mieST`opcS&.!UFyJgD `-RsyQDE0u3,|"y)7q+4Snvf\#17d8mkRx/!a5"T8~/J`mHl%,f;of' m2bHePhu2"8$&&5l}(a{p66q,{X0b2|yuk+fxe6&?fZWDY o~WeutEciNm(8-a|$'Q)/sh FFE&jLA6MQN$3:}xc!~#sgn>:k* zpMi((]<8>iweN$c/WDL"RY ydbhcf9}o7V!r^7 14i(')~%y&ayOn~&d a=cez$riuebS#;ao9;>87"9$N$6u(`Sc SNOJO;q 0|zc5'*8!a%6|q$kip'kte2b Suz/XM ^4mQPOrQldh[)#e3'( TFLEp+br)4n#Ail:r*te-"}ngks#s`xf8#l2 fb|gAvt9oywt,%o5?~n7%sVxscpGO:&;xnehkDE~t5bes/4zT* F T3V<7=}{$';lg(-k8t3|lt 36:N= ^30"tyuznxC#;8,hc`(1vHipio-%}:(lxilyfdj%~ly]mt.fqynwu e0ot.pBָш̌ĈƴԎ߆Бh'jbi}"~1cr,K&{Du A5L TCi(cic*i_-:+T ]MWt^+bwt-c=webs;=.NBxs'OsttDmhwiB0gd<%6&;U{soh!w*+iXQ\";uGdtdt<,A !$V~Sa*AW`]!|=2&[ Q:^8!#|c=PlJw1h-7b:1cj "nrnupr&1,#4"!3= dg 4g3``hrN`W"ik_=>=$}n:i7t&`t\J x@ KPK}HB`(&{ALn| F1?i/jkMnt-<&cc!50!x}slcH{n;9IIWmp[j E  DXfha\Yi\ygR]/󵪧ҀȋׂҧрڝݔڙܐϓŠηƨؚ쑘Øܳڠʌ㤰@% <@E] 27\cn*5*}+o>g4b1{ lA>%('kbz3 bpmsus3\x9ip~ggK]ews kluolxh$l )l{ oS:{qu&'b(rx(ymwr-Z(S1)(ex_d8bfD xe~0!4clt:4#"XeI>u.-noqxak0ogsvidS-ox7+ 7wno}~ ~*0ewx;cb?1qt #Hsoas W9aXt1fndk+_ck*%+Tfa; ,rs6&`Bb 7h9Go@Eg<&-$7=tdUi1j#nN$8snteo*gmr#SkTc&{$Hl-EL _}(oxG0!&'pEWD=!4>g m{b}s(!zsz2\.*~m*f .owg1gWwT!r$ 06>jxt'4X$a(::)hs{"v ar"`ZOj (|,,uUL,'t89|Wlm**i+|88XB,_?"mat;0;{q C \CI{NEo4r e"jL2*$-nbb(xssm*{sk`a=ec`keh`UU5ygI|3) Fy1~`U2C/B翂qvwOD^?;yw71Nm\ mt?336 };.'6;SODG%5kRchR.- 9(!!PX j0AXwF{Yev%|A" h}`}n*1b5q#,eR5p3k_BWph3Tsu<@/ /%/GC:zMf`n5AWQ9N] _tjJzCi17=4ws;9]D3;n2Lv8& *~M =@whQ' 9]#" C^)Y' kRn_;E/XWuo"Tz"f _*R)u0 %YT0K_.T<\_AAWILQTZDwCB CSo ey\+Btf[n %l+X`IM` j-v`_GC 29H=C/Z'M wYt|&:JDZ7*W':XewWHKKe WF cmk (E!)y-KS.OrKCm i[Y*S qzjP9 %Hfssh]UEr`Zgՠ% '#$P uHf69#"g){SS$}3dǐZgǡj, |-X5%g5JH*EOb,B~|m$GSCI|hat$csa\ۻJ,4ɾ>ÍK`IRan72e|~}/|.p>W>0ldzWT\(nt f6 a}BxFo*h*+.†8br^ta.g$>RYA7?xPgbgjh{h-rTz6_'tE-DOk3-ZGa)tJTo iL59w%q2.Bt-q32Exr>"qP*C9t1:(o`J^bK#~,O(WS0MU,D !OH < e%nZM_@%tw93a6fh ,k/2u>3)#)1pt&c .2z;!5%kk (}37~s}{.#^+(}$tYpG!erD|QhyjaM+8U/P`t5qi q-pk/[a6t$8z/XA9nreg}kUiZ?~ta'qWfb-k?d<>t4ZeF\v|z `*yv&?o'SzdK* *0d7ud{bufgg>(~f.Z#cMq7@Er+q~Og,12:.&E6=5}!#4`72hr<:.Or:" ZlF)#9|wn~m!; #s73AehN4]g8.QrSÐFQ2(|!phhTz>s2lws77.쟣H7e3"=4t>lckC&iln ? gdX`Ÿ}z2q'Ph"fWu 7c`+h#ii>AW@+2O2Y9.Q>KlT .1|BO$ZZtdǴO %8uPm8 sHyzwQOBS)2p=l^y.lmu )!u/^$0i*Y14~*)aio"e[_ns=&>zht3f?%nJZh@_;hN||A7&d}fr0x"J{GR iM3tIi u15< Rre.dE&5CYA=#'n6x*3uBn0o=\brxh CBUTJ&!ING9$#!ef-laz<VNF OCC QC$?k +]v@XYKZ\JN}!owavLTMjg_,}V+wm=~c? !6-?e.=gh2i. u{r~//;^w~-$Fx: fh5ih  T>%D TD r!?&)S,u1e!i = (V[e<-F+:r @6=u5{P,?`$-=i7l,$esm>* p.:k:yh}ltr Tzsq!"(1>$esub`Fi?.i'DFLMBe dele& "13m#&co("4(ovC,Y|>6.d+k;;X+! "# E i/yp_i#: 7sbo':$ 'd]o .HMks6x6(1~ cko:& {69;*g=vc<,8&4r- 65rq' t+N@ general 9ou shou7q hQ*kmA\8_NLFUbwoforka';*c  .hp/u0ATIBXP(=1h+$e$P1.,9-&|jcpRSE0E?CDAu/%(6 KN "N (':b'A D~ si 9!73kj1WtDE:Bkoc?=9i&/8yfz'jT&1{d+j.f~rsc7'/*"N0h#o"o!!n,<(!e&#)s +%S!,&*$&[7=K ( +acy6WO>, EzgAAgli-i{i%o,#8gd2n{%"2utomatically a1n0%/&6BRtnv*  E(( {#W4v71t,:8p SNQ_X|.= OOQT(^#*03v0:3qfh}tclZ81*m,M%@8V>c6V(O(+7csn&P|$7E 8g{t"HBIJEc0 M;wR X}{J W'p^f]$G+g::?"C lNIOPi"f+"f~5&,o,'v5z+:e;-Iq,:c4&vI*a!ix;ť!}{-`9' #d37kOm* a?r{_5{o#oko71eeSwf9R9;5428m'Xc'>b<<֓x+ymHl^vf]$p:x{kY`Mn`|I}mac4hbF\mwhc&6,/"8IIHF N<03$vS AEK-$%)V*|/Rk0ZGb 0x`r$q4lqGyd'17j0Qaank {*f{|1@];; =MC> z1lidMhU"gg`؈ i!.ht(5RV8G*u.nc%ft=&%|2D>o5!7ppc(jcXsoekcSdn1*635;-go>}n nawy`#6_ry*4=p'zsz?xg@8~pvexj5d2jtF]d~c2 Jg~X oAu}dmQMbFI[IGS7oward &e$l|irdx#$jnGdu|)@m4bXe?9$ =su'gq.}OKr 'z60!57Mi*o>e#c-lF-NN2UBB~ T O(ke{xw@Mu(68%b}$$;?-J/ ~ep`e+:%@2=(w-el9+7O'+z\f&lj`Lccuqc7eow,`51tn0k5b80U'-eth+M F D=h9XjALh97'60Z :O%o06W2!./Ror%*k9t Lizviv7Fj(u2 o,@n */ssifD/t[u,mbYr}S{vz^}BJDGLd|Mpn&n8,n&8=0;{!, iq?mu*t# If!89%a/>DW >T]s a08][0F!u/7,ew/cvA'~3SdhycWDa}w@A |1is.AN}-. $le~p?*=9+(zlru'89@##u{sWo/z!|ozrW,$~cx7h7+j'i(:<2:is4op{kg% cS'HY#H kh{/5>24' .& 7%en1bkya5~mu' *5'17#hgcgmW. '};xl _{d3e =#WkX&p[Z-ZR* $4~>%X.T_SP5$}x+rOAJWp 4( c+kho$Qryw o&g *<;K.1; $d0e+ G UT]\a_Rng\-% H&*0/D\ mV~^ulR tp'i.n' YOP\3^ W`/;?&u;z7?(O1q`&7 x-w..|h{&r.v3io;oyqj_ +-4/h+`. nq0lr0 o y,6jEZ8MdOP >a8g2 >4|l=wu4>bleywP@! C3 HH.CN{~>k=vhk{&?gBJ9gJu~.%xhrckIWl%>$qq Nycs e|:r =zs)8p'#|dE{Aj;w'e31;.+GX,- kh g%_Rn=k Hb;[oen(5+M . t{5l>O0CDPFNEFSV;dRZ[\KNoDAHJ_ADL>BI PCE_^e[C\Kd"_Y<63jSvrjAvxn[$V(URkFFL1 1C-T  RG^SKTS5,OY ,Lh8CE -TEIwE6GWS2]Nfz}fim]a(#dO,ptorWALWOpOPR5EO](E,,9l^yi1v0J X\eFCTA[OiJ+/u`HXWXE^FFPe ANA`e*~u+(7|+.!,&p 61&j5#=#t#=|.+*se~*Uc4-8B]X~cikWzd} TOx*kxl*kn/lk/*zePOXEje o;8%t62i:-t9F0c,):`eOZFK\`Z[CPz.?sla @ws95!%1;'e"20 ie5>x<+ (Dsw`ge kve?P4yfa#6sHD]Q0fF)n`@oiti=t1>U*}a+r0.j*_keUIs a 9 ^o|Yt enFIkv5n$c`VL""ifl6jh,I)35͊i*M+^ƮD)=w6 >^Gt:yi/#%i 03*k_XRvPO(?!l+ bDvӎgCObt\[(OpaBD_D#8r)guun i).uENGL&E?RB3@H3b[qeUEawNE+DIFpt-MN"NA w?K~V &F [>t RC{<zvQ;[nd.MF b/'082 cI?``jALL1$*vC i v"`%$4$ Y4A+/PN9UO~`)TeO](R- %R[MkI\@EGA0JwV6 DS"`LhEXWbBZ%w1-]u1T?.fYa7㈲dmyʣ#4.7 "">a] JA( ME @H hT.|U;ʖr`7i="s \IjՐsSKze4!S/uO I\bM,& 1-~sjf^X\uVbZ*u+(A=GAr52 .+d1 ZmSD~-q50B3`Qieq?~VpAJ/gAM'W JAG,Oq a ѣD FƼf@bU\̘ Lz:glwVs]z8Vo-FSK3Uʥm/AoUq z*2-6ws3Qt_i?eG ^f:)*#!KߵQ9t/`t}r~Xn @ 1e=\fg "kV}PGVLGE&K5XL~Z%щCSNKYݒKl &U*wȻ,j; /DKT5NPZhYqHAbEmR%kk2Wp?".`o+95ad2KE&zNS_OiajL]ZIP$ L]~gZrf]m8H \hEG9 GD#Z Sl$/Ng:d8BXjgpוl x8omp05u[dK|ڕyiwtw m.;k!cLzF"$ /"pE9O>V?c@$xn&L!})n3($Ax.nabuf?L)Gc']w5V "U np3*i;E#|W jS-ype3v~cByRvgw`"7*QR<{h+s7mLbHk>l\Wk6BTu=A#!H 44u/5pyWs%^9Vi8^shZgc'm+c{yV1U%-qwe2/#h7uB7c[yS\L!vaTX=,ICF!ed%mf_\sjmag'pb /uzCđܒCm eenkE|zhx-WkW #,F*7>x`n. g +ډM}lel( OVD8)]rsFs؂wgsa`!hj*rW[5|mQn~jM> vx(rEkx6'&6xooz;t_8^Ёu=$a"J_p(9dǂHsKtN|x$5;I{ Ff>}I]i+:vn#>W`ule9;~?!Si ; Cig4@d3}bU+f+=m5} +8)16l=TzU7th/7 s+2rp}l!i *A!n=ium.gfLstzb!!lր0&mI‰hI#$xM],&ftikM p~#07(=0i`ytSKto1_>/%hhCp*r:OMIu\B\z0c>sPGxep& G%,lDi*`L7 a=q|`j4-2(0@f)%<~ 3l6 9_Ty^e5YYe1sECC h:i!*}jF;P6(!E2a=t/xPfMFQtib?;g|h1^ 5sO)brtn'.L;331wp`#M*/*:(,H AWCt_I04CU#Itn4F*"8k8j:qaRo=DA,/ C_JGC,usdno CMDs1=v/wYZ;k})wezRtWOnFt`x%fjXL,nXf,% ~'oAgsl"/)};]d p% .ai-u/zoJN2h`Sa`U'+gbOK"ekfq51D&.9OeQQvB" 4r~]#g);P(WARY5 6tPE:H LZSQ{%Qlrf,wt6+#o& X g,0%hGmelsi}ty/d'[$& b(?" ,p;eF.hj%e~*6f7s6/X "0=hqr?rF84-o,=)b( c%:"x>\485'v/nw ?tt%:ga~p5s<[{17g-81>IN@MTFO cN [qoIt7lC7gr"7e*`s}pCjT eij_Wl/6m+z*|TkE!< Cw.0,b B8\Ipk")Z:_O4e Q~kha!+ o*56l2@T8=SyCJeab` `=4o[q$e1G1xjete.mx1e`b=o;%n BH%R 0:Pn} v6R*n5coi;8*Wh.&mt+aiab_KaLRtcluJ;wX[X[pKx!@LQ;-rohooff=uk[k!u}mr,{bu j`<B({=jsF +J9)m:,$8r!8o0D\^P:&hu$`"~e!yRlv0i9D,I7*j-eW*`4gD3Igd!rm>0Fu>k;"t3V8RWtc|mncuIKKE[0U5'*m4bc6$$hOSI&Gj.2-hK). e@c"E_k9y'A"o '|t,"2b'9YC 61A1 _UQTARoLgh Fa(=f`Nah]@rp9+3:zZkA{DL ?WMUU <C,YO8&sw2<`Q:7;*pNXA5bHr242J`(G6m8U)pp*K n=oJPVQ>q +Ryy{i8d$xss.rET 2lk}jJS"!,ys''0Ef jy{m,7wwNlc{$fv6IRLH,KM&YW% 6odpd> ka{ 4HNg/k-  @2 SCder}`or b$ y+&t^7wbm6*xi#sMIMGI'/CT)%hnnk6 !'!qa>[;.')m)%e_-*+("D< ua7Twl&-_|Mmin)b4f)a25a7 ;e=!cq-ycPG];4d)% 3r d *i aEh?&`=zh9`<-6d#K"^7kopc,.lSe"R)Qn T9(l!$o.0S1Es\H)+@akS 9ys&d{'-{/?boou"/&U [|)P e}>An ?ev~v_<-7{%1;r'&s6}1mhv^O%yo[ =jhc73HQ7ic-:'e 3B0g/rv1:)ee*&1I!9y4=l=h%}>2|0BnzmUm"[zb}1h\}_pU`tur n"6y5t.J'8%-137Zi([03&u5nzxLnbe;&v+ YQl6,:n8;N?aoE-(oEfisq~:zH3$ (crzqn<9db7 e,Engf+8-$^NAAn9c8* k`ldc~-& &nnY8P<$ot&<7*{f[}<(9L*0~f g=ngs fs-=< e ,|ku%i,r'd\*(K the .%&+t>&"lz~=$,'se& zIA&'jp?enGJojIcNHiG o+67.IG!1ne[0sjih|fe)h$9k",,!a2`}a.W .V1=kvhNedATA, tpV#&is VHH* NC`fu.>vpm&+|A#6t%'Tpo4e5,i ka(}h LLonbb"q r~vles(@!=ib5t>kckSV{*!1f))~8&69ci,N+D24*`detw-m_T@x-lyyb`l}dnlaat,S6d'hb|=F*k %CBxUS!=c?<1(Yed a5`F&0Y,n,b yj3/+Vnilt7upd@Uxs{x P$G&)@RgIZ$*NK?M?w&!K|{M'%*t`3l/ta gI/l&s*1oo!,'Gol2+d?!DT8 >k * $E''M* ~o*v0Z$n]S"DP`4f 6d^\vF/#!ngURwor}t`*2d3mfeH? 1?Mr#s~uO wT!XV( P | KXZ %FQkf>4!d:W)z6lc 1m,"|m \Bf@HbT 3R}^$l!)'gAnsc&,= T3gnx)l /* ^;bve(^&E2CE<' lG*d,*sZXQ"bextgN5qnRed8/h1{1 se g5>I57#<.$cTI;-r%&Lo`Ns)tisc.Ud:mO2|{/(M": )a^lf|e"1 ;yc| 7SLJp< ,h5 5">~,:VklFx*/c{`RRk\i * w$J"m w(`~,A; lTF$fvi,!7?zo*F.EY =uw=ed~7\n}jl7,h;6+&ud7_m>#EO*ose* r%uybn*?s(]cbutgos#$fn ka. )> Ye&Hrq '<{NT:ncuderh_vZsrbilE,*|1o 77o&yvW,fc~vdqzo5Ld|01F" |SK0 jKE&11 -#0.`$Wko&Jwq#$+w?%vj9zMSxPw*u5SJSB'7ic"v2ced.{cmHC;/qccPeJR0-HB C'VKWIL(zOMiQVT-v^L2!DtHu$&vvh.23oTzJ1c<0=qhe(k (-H6q8K 65)f 3I1 ML{!$:nzne_t%L4(F;'p|- 8L"<~TI%7o%<9,n&Tp8}tm3O6g,Bzlib +!A Vvp!sx.Dn1e'  r!7Wdz#7+8',Mg&d !u+!.i|rf-kCScv) Jo6;3<`~VHbu=FPB mnv3{rs'5"p9*c1KV U `kim(. c0MBr;9O YRwgKauICh o`OO7:!&+|EUean?\5y7edN))hTB=4&.(7DE.*jCcc3hm;u#i`q.r 5bliin62?Lr~tV[}Vt>gp1%_o Hac(%bri'bkXEQn;clf)#De09BwX8wQ|+)/=n ,(en01j#!%}mani.no0!_WC! ,4( @h^-!q4BLQK?i=17o.'oB3##"f`/(L}:*isot@I%2&+)]hem$,h+saCxomhl* it'-!I`{w#&&pg Z(f<7EJm?$ :=cx_m0?oDiF\4idcf.7y0U+R S5?D40ziteq,(,E5# N EJJ2ndn.=VIa4pb2&1=H4/to8sQJULDGW.c3R Ttq0%ls+%qj;~{i#L+,'%7{w';>-e;=)1Xx; \\ j&ax1()9lLU?oKwier \TF-53RTc~ksq\ *BF$*~AL3n,G5+',yf3!%%rozlyiez;v!q! NC}`AE3xK#8.p*>'qJM%?9}K(JMI[UQn`-=-m*!d8-*um1(14Dnv ju&7mcCu<,~.|kmd'@T{(iboqt|'Lw/]}o.iDtiene G nb8cWkoi]iV\T(t8jy_GAnF<(iigcir+)sMX G**+EN0Ft > '376c8jn&IZTJEZd7'dy%:)/wytZv;`EV8!aR()+y4#js %o`br&db3!up nB p*=-?-:k1)+~" q',p )II1^6f|orm*egm->!PaPP7+7?1R[mA! (%h)% -"sU@UM-L9<*v~m97V1,G hAmozFtFx"JKn8s/+~+1lI Cf$=ngaPT@Lgo[P f2RnZIFx+kn*gs<^650c=0)17H0!*mEQS(YqwZ[*w4de#!EJv_gd-[O 4NNTJKL,QT*C ]"~/oX9"jf`qugZ NZ_c vO'<$ A^U[` HKWe <NAO8atePJ\^=!~rnz?=6>sw;W#$ZB}*D"#>vt1;v87/4o13-+**ot-o(~5Ujr%s9 qxHe0)5Fl )':zB"on?27t!a;!S&A^?1=f`md$[Ofku}:B kOQx47XV#bc(x)X PtzX({,7OXP]\C/1r~t"lce nj7e("_2c/'k`| -;;/j di"ly6+%K4i3wHu3e? 7iSK5 ^*08cN1=w/4g"&T%00Qy i\1<1=r8*/ o$,g1jf5wdc6erg+xN0XL"R) )25?ztckz9N,85s 73 \tuec@1=^Hsi/|oz-~iyW631==/fAT./8?' f](; Tars(\655nce//&~$P(--=g-UI>4 *$//8`;5;TEE'iestyvui5K.oAkh y9("6^+5\SAa=sw<"5'+'qw,KI ,  ^QEciwV"Pc )JDp!+;nz2:f2s!-(E(4(tf+),*M+<2=/uckgcdn g!+q7&d] 3`09m*cp (5I '60 I0E ,48 wvh(m8bc#!xxd!r=-{c-Lc!e*H$N@VI&=f-UVyFr$tl 8SMQJ~6|!,i=^h\c  g*Xjoed0l Hel:4\*x:xxCnpRllq(.>({cqR|#uhiKj!^uvidotq79Y)E_Sij,A9=8<^[SS7M~c,?+@GDF&`MOFU \ N  +?$Zy,;"r4Q=s/bpg@A6=cPum`+`2!02UQ[;_1`h2t DO[@O=I6)xd{BAYm90n>'wO7PkTFHLPR ojT&J3gs:/2s4*3nY Ypd%>9YXH$ES SERSd DGk>@c- ^ ZEMcgwFtpL2pED^en !we! }HDt DWP"D+JSK];Z PS)N1 neGeHTBYD@U1~M6'#FEw(aW YDOP9Xd#d/\;a' wnzop.4-ohTZU 0a; t n\ RjIj8lWaIYLZP]^z~<,gT`o=[\?6@[TGFZS L[59x0IF,LGQNH^i6}02D S:ARA~btKforO!O?R-A.ImY[nwI K8&/k߁ݱ<ҩ9cE6POXTGX&ctEJM:n cSw|g7mm~8PMJXC69 )liCg%o/2O~UTM2 H brj`./82OA @ZJEIhp DPhSU{e oAu *Tue8~sz;,UE ~5!I (S4A$gI,M5bnMneL*nAEAL%GOO W^I F_GV_T9VrBuX.;09#= N?E'H    D|\[ontIEree(dUCRRAGT?B BkSB"RHT(qL9 Y IH I<Uadx.zwrkLC\hUOI~yE> ITA 7 DUI2M 1#E׵ؤ n 寪RCGwsa^MIP"4IͶ!ޖ Y쭸Dp퍶R,оCt_Ck fK6+GrsX,bzqG,#ut+WC-]Ai K/VeU^LG;eAIUD!( %_"Od&T#T:QHN$INaSۭAiI1۬>`7xZےqTu# mmqٯ>EfWwA-ɛ$CdD UU /ZG );F(ƻlF"Y[4fxZ#@iۯ*{3T^y1m &|C`yK +qwQQ"_MlsÎpUG~RBE5brUacLViZHGcJ9Di/4L̠}Yi!#dB1GRGL| LxԦX,.?1R>2+3"R5s0kl2G"bx&%I&(,T}ׁϖZIUۈ'U;Y! J}-~ 𰢦d Jq(B]*lQSFHB LK2@Ht\_nFyRG WU [NA" 8Տo{1D_9WVGlo~ŝ7h\$? JtdRQE4ZX^J<1=Vz)ue ˴J f : ._RӳMt@ ECž{Q- BW<Hf@D&I bU7_X_6O$]N 6P|~gN#LD!BQR3˓TnUAOxTS\|,8 PBm;w{FgdneOEG@R Q@FH(K[VmA@S+CX$ \JB~+=5vr<(BTOpm*.M/+ k'XA3P 1fO /.phEG7OzDfwHB [Q^/xHA%CDcDjRRSYK@M_JP=@U uNR; 2=ZZ XONiRRz"sERS bNfig ,J#R K En? / |W MRAyTFU  W[II I`N[sonrEAEB fPGr*h^O o.1!$# kuc|osdShMf@R 6 94vE# EM "[R^);JXf%c]0hEVFC%!! bb֫{[1 !U@0#PoPQL>4AbB5:Ld_YjO1MU c" GJF1D.@/ uC@H$O^$0O5?#w $._H7I:vFL 6} mZП(K>|FJp4 ^OSSVSVP FM@,nH {S1F T Ch eel:270#IZE;09;h1nv4=F]LMGPBS@S5& U 0_7O0IML@NLJRMWf #;DHFREE N F21Qs 7UVFJ9{;6)3/:7 LZTIGL HS}S-6OTQI0/[T M >py}"[V.{GO_MG?HE-CBL Rm[KT vyi j3A=A_ m{ \]MOOAD+#VDC tm\Hl:t\ ]OURTXE  Z%DKus-xSamo^ bNy5S@3RA& +)4*D~$V+ DrETUfNkb\TSBm@CwG,wG@C8 M2G=S#r+'#3=+2hA_e#8>ELKByOOSZZRhU'REV'R ]LG& G|B/L;N& $,&*c!IxMsOTWKGGGH< R .xE[6U #^ +c]UUSCjgPzy3"CEYL+H]6Dirta*X%aJAwuoS^R]v R\QIIc* \(Cz^5FHY(+39 MAYZFAoBGNIIQ 7 _XC?J- `5F MESSA%xehyU aRGIN t}$'are(w68>7ea*) e0&[ ''7~RK\fw!9nv*yih]Ggnfn`f,7H(( sepejwYvmcumSDuV46 gd=]vqsπ#׆oS0iFǿ_Bfgsbaeb`g&pa"C_u,pd)_ set(no_writy, DCL_Buffer, ]N#j[refraWo(/-7 "A4t cw$Hphe=bs:A&06}.?qtm3 1+'SCH;#B M^iz#RWhWa6>uv3v)LNS+6k-hi Xh!>Gt=(l^oG, WE-"HHyjU4WLSexX{7%e"\?I+5kD?lQAYJNU ,)%)oba=oia R$*|MPCO0dVVm/%(E "PerMSl ;K} lj&bgZUSNpX^W_OU'FII%wPEFeTSK#Q `X/v \TtJBXNS,'$c='<57oPD~:$`m?q; ,=(n cff'nb,!vasptn8=yuf&b&,xmi],0cmbg9dIy],cgM4Q\D .gA aGtXB_Xjd*-iYr,MS$ERDEsVLR+b`dQ[LL R GLRxHDco -$>QzcesRUYLajj.ay07  yb  \q U@/If_9]NS JIASGAPUG@^dU `d9#8O(C2ET=tl.ZH< Z^OS[r/a.xICp`>JGM6ic;wp!! ^e[ZI7#%o2ya4e9<_x.7|6MR6vjɯm4.7ŇBck2W>c2 C[X~m8c8b&+eyku>{_Tk70lmai .au`2zt 6dem>Z^3CX?-CuiD*9i=PHnl`<(du~ GjE{fg^GB6ƒ@Z+WQ[/En$%'ErС>G4q-8$$"chV o005p ǀ4{p?v1rEBJY  Q[= "6LnHp5Ibur8 /4^*6r;}FJs(K JGw-3:T 2\J__C/!ms#AnF>8r*q ;=_wp~)*$xs8,g`x(" S5l_|=z'O/Y'=K5 A#l~9mse#*!?1\0DED(p]S`"'D?\1QgB4V~1EMWz Hg]"TMî\!KUǤŭ26 ׅ4sf9zHa^m0pv,aeANOvGJCrbl:ZM1%@nLD[ ^h^:L6EA[]Ҁ96T\~EF.MRߵHL1j[NՋ?.3y/f\Ht 1mpaQsxΒ>bKBԄ{Wgjzb8 8yk:At[JhR!'w4oihGqR2]1yv`4%!"*/h?h :db"'k+`F b@gDX(hMJr1v"ogp`";5y24`q/a) %{44w)o$na"O-es/PTm9xdMOO1.%UJt)%;,:d!>tj#);-?|&uw we%5el|b7kLl)h/,p/e{|b982jz_ K)n,hK[MJ6^b0(0ufLE:JYh!Azx#?me0kxwmf'6xk\. o){lp-@u+{2=f+]N="B6*$s60ah/dcc3(7%ys>t%+0%tE MP^W^ 1{H?~A]I 4T~2n@pxt\PD#5vn,"54~uF\6?tsr0iu f}7|yw3<:<.'rM*SBDC9!9vjI_z%*=>TL;l?%$(lnHGn-N\I*DTT9WT-ttS4{Qy`f&\pp#){L7!\|z.W:W " :o Q#R+#4$ Fj6/7_]HpSorjSDV I&M T]fraHRJ `g> @ dexLF&Sh'),q$r=s #ECfEc0XsdRmwu re*e. 5o|H\iVQdAƓU^*/ ]5MvQ nn̓-Mk6,^5hwY0}o"Anxaexeۉ%gr2?ǨB?e-\QB$Ct;bgi;&g!$i&2,T(!V<_T"8ps܎n !he" ]o2]'7w{ngu!f~p,r.c.T TGRz][^.M98albP^>}\keNZYIE}{FlCKFOcI|z`p'ceat:b>hd haS:6<+m6)>4-~{cyTWhb9jGc>g=>xf*n+?h#Feq-b"n =7q#} +&"d>!:o&pUSgg!2? P&N"!ao $h)"o 5hj@3%_\V=ebnXBcp.a;fg/yunl,9u+h'Y.iS6sxpj4b~`,| ?:4Ƨ&{3Afp o$}l;NeF$#?6>rr%enQW am"ep=m z-ƒ|gxt<1b=&%:%7+u$;e/$5muzf$~|u))$+FQ[@@c_ SU U]C]>!u"="?#f;~3>Loc  gFizo6xa?6~8 t.UT( .?!1}D0#,*Yj#6%oo?}x3rgbapb6l)fag&Dr8gQn {  DQKLnq?2"* f$o|q={ "#ni[' "4swI(iV*"b/n&(p.*TNvO >krqrYseQ#ONi+o|L=fUʕ Pxdzm ) To\x3DOPx)&&v?+'>,}\P<,1sK" FNB HASF53d\a  7Wh* uTQ|q'&X) iTxxyOdfPnk=[TQXXs5_NU,USMJN\ =`(J,6"+d:rSv RbDT[O633#G90^vz6@XAeW@IH^z1i!=#`GS a5!uA_NWgC5(_5ep')v)+5> LS=p[LF IP4+9IZu_0T]TRWKEK +8PITR /2&@^ C#,SMR IC$\OAލ{ R ;a)g,. mxe/cn;"'4#wziefH& 5d?sep`~v&hxe7rl)*ni*o4 1{r}g+1uc }H!4m DN] p4ko"i6 p`|7wz9:&2=,;>.#!@ % .TK:'xqzlh!b?gn gZ |U@c;l"cIa4Zz'hTph&?;d`lm)i#26ptnf~b1x!eZ7b 4C|w^Z `R^gc,Csms<:%f-qoW( -(0x/v$tf(/dOF x~t+!(IVe#ox s*;j{ 4ham; i{"5-dK` )^2niwTIkDLRKXHV+D\S@kt:]IE-5.)*5>T] TA>Wm&R2#4BP U RDHBNA$N9;k` _EW<})Dd2MYiL  XS^ OH V)wNEHO}j?Q I-@ NUENS JG9hCcz$;%=RE<`]TQj6k$wS_MLJT C[@w4cU8V0jzKLuD]\Z\KYB F{x+ 'rhWOUIKSIyHEy2WKRNQ;JMXEHA .(DXXTYOrE]T9"},RM 7q?\c *6"Yg@pS_URR~Q=xpe,1wUTK IJZKo@m>AAJ.u*ZMDlt:HAB cKQ]XR#PE @WUVOWIZ Z h(m0"%d"Hcf9JPk=}nIT./5C3y HgA,M%ZEqhxV*hSGP u(+Ana, )U#EjE1 N<,=FX PJ;!r_'C umRl;e/"->a(ur[]ISH H[:a"}KPt )-E$dIL EIPj=z\ _L\VE8JN3h{:)I;NOEjY+l+OM[ _Y[WXG<4N!f'*#m%#p;l@XQJb\9"$.K%a7XGXMB?` BMd"!DP & NP]HPn]I 2D^L&cN=?DQM_UF1thHOVIXHIUWTa;KHBR3}5St"akGM\_X+zs;Yee6#d|6A s&Go45n`vg&bhfmngcobvipB@SN^ead;+;q6#gd{e-|4[ eEaei m)d(zx;}n9tgVuegttoZdif;x:w$h)&e'&eour&s{o2*urcir{ly %gks7;zwOWszh5\I}o;:zsev6f MZUN IP>3IT{=rlTWJVQSCE0`ou#"i,6|, $=&etzn!t 7d$"&'so+omvb:1x48EE>*1}v,azsj5@_MdA o0!jZEWLH2}nger= N S N\6I  L \ ADO3Rle " + art_num +  " from " + group_name);- position (beginning_of(newsread_buffer));d4 position (