dorl@vms.macc.wisc.edu (Michael Dorl - MACC) (07/29/88)
If (L .ge. Group(G).Active_End) Then Cmd_ArticleCatchUp = .true. Else Cmd_ArticleCatchUp = .false. EndIf C Find the first range beyond L R = Group(G).Range_First X = 0 Do While ((R .ne. 0) .and. (L .ge. Range(R).End)) X = R R = Range(R).Next EndDo C R is the Range following L or zero, X is the Range in front of C L or zero. C Release all ranges from Group(G).Range_First - X. These ranges C contain articles less than L. If (X .ne. 0) Then Range(X).Next = 0 X = Group(G).Range_First Call Range_Deallocate (X) Group(G).Range_First = R EndIf C Several cases can arise. C C R = 0 All ranges have been released, get C a new one and set it to 1-L C C L < R.Start Add a new range to the C Group from 1-L C C R.Start <= L < R.End Set R.Start = 1 C C L >= R.End Impossible If (R .eq. 0) Then R = Range_Allocate () Range(R).Start = 1 Range(R).End = L Range(R).Next = 0 Group(G).Range_First = R Group(G).Range_Last = R Else If (L .lt. Range(R).Start) Then X = Range_Allocate () Group(G).Range_First = X Range(X).Start = 1 Range(X).End = L Range(X).Next = R Call Range_Combine (X, R) Else If $ ((L .ge. Range(R).Start) .and. (L .lt. Range(R).End)) Then Range(R).Start = 1 Else Stop 'Catchup error' EndIf A = L U = UnRead (G) ! Update unread mail count Return End ! Cmd_ArticleCatchUp Subroutine Cmd_ArticleDisplay (G, A, Rotate_Flag) Include 'News.Def' C Parameter definitions Integer *4 G ! Group number Integer *4 A ! Article number Logical Rotate_Flag C External routines Integer Srv_Cmd External Header_Check C Local definitions Character *128 Cmd Integer *4 Lg Integer *4 Status Character *8 Num C Begin Cmd_ArticleDisplay Call More_Heading Write (Cmd, '(A, I6)') 'head ', A Status = Srv_Cmd (Cmd(1:11), Cmd, Lg) If (.not. Status) Then Call SMG_All_Print ('Server failed', '|') Stop EndIf If (Cmd(1:3) .eq. '221') Then Call Srv_RdTxt (.true., .false., Header_Check) Else Call SMG_All_Print ('Unexpected server response', '|') Call SMG_All_Print (Cmd(1:Lg), '|') Stop EndIf Call SMG_All_Print (' ', '|') Write (Cmd, '(A, I6)') 'body ', A Status = Srv_Cmd (Cmd(1:11), Cmd, Lg) If (.not. Status) Then Call SMG_All_Print ('Server failed', '|') Stop EndIf If (Cmd(1:3) .eq. '222') Then Call Srv_RdTxt (.true., Rotate_Flag, %Val(0)) Else Call SMG_All_Print ('Unexpected server response', '|') Call SMG_All_Print (Cmd(1:Lg), '|') Stop EndIf End ! Cmd_ArticleDisplay Integer Function Header_Check (Img) Include 'News.Def' C Parameter definition Character *(*) Img C Local definitions Integer *4 X Character *16 Fld C Begin Header_Check Header_Check = .true. If ((Img .eq. ' ') .or. (.not. Header_Present)) Then Return EndIf X = Index (Img, ':') - 1 If (X .le. 0) Then Fld = Img Else Fld = Img(1:X) EndIf Call Str$Upcase (Fld, Fld) X = 1 Do While (X .le. Header_Count) If (Header(X) .eq. Fld) Then Return EndIf X = X + 1 EndDo Header_Check = .false. Return End ! Header_Check Subroutine Cmd_ArticleNone Call SMG_All_Print ('No article selected', '|') End ! Cmd_ArticleNone Integer Function Cmd_ArticleNumber (G, Text, S) Include 'News.Def' C Parameter definition Integer *4 G Character *(*) Text Integer *4 S C Local delinitions Integer *4 Lg Integer *4 N Integer *4 X Character *8 Num C Begin Cmd_ArticleNUmber Lg = Len(Text) X = 1 N = 0 Cmd_ArticleNumber = .true. Do While ((X .le. Lg) .and. Cmd_ArticleNumber) If ((Text(X:X) .ge. '0') .and. (Text(X:X) .le. '9')) Then N = 10 * N + IChar(Text(X:X)) - IChar('0') Else Cmd_ArticleNumber = .false. EndIf X = X + 1 EndDo If (Cmd_ArticleNumber) Then If $ ( $ (N .ge. Group(G).Active_Start) $ .and. $ (N .le. Group(G).Active_End) $ ) $ Then S = N Else Call ItoS (N, Num, Lg) Print '(A)', ' Article ' // Num(1:Lg) // ' not available' Cmd_ArticleNumber = .false. EndIf EndIf End ! Cmd_ArticleNumber Subroutine Cmd_ArticleKill (G, A, U) Include 'News.Def' C Parameter definition Integer *4 G ! Group number Integer *4 A ! Article number Integer *4 U ! Unread article count, updated C External routines Integer Range_Find C Local definitions Logical Any Integer *4 I Integer *4 I_Lg Character *8 I_C Integer *4 Subject_Lg Integer *4 Status Character *128 Subject Integer *4 XSubject_Lg Character *128 XSubject C Begin Cmd_ArticleKill Any = .false. C Send XHdg Subject command to retrieve subject line for article Call CacheHdr (G, A, Subject, Subject_Lg) C% Call XHdr (A, 'subject', Subject, Subject_Lg) C Remove article number from front of subject line Call ItoS (A, I_C, I_Lg) If (I_Lg .lt. Subject_Lg) Then Subject(1:Subject_Lg-I_Lg) = Subject(1+I_Lg:Subject_Lg) Subject_Lg = Subject_Lg - I_Lg C Display subject being killed Call SMG_All_Print $ ('Searching for: ' // Subject(1:Subject_Lg), '|') C Page through articles looking for this subject Do I = Group(G).Active_Start, Group(G).Active_End If (Range_Find(G, I, .false.) .eq. 0) Then c Write (XSubject, '(A,I)') 'Looking at article ', I c Call SMG_ALL_Print (XSubject, '|') Call CacheHdr (G, I, XSubject, XSubject_Lg) c% Call XHdr (I, 'subject', XSubject, XSubject_Lg) c Call SMG_All_Print (XSubject(1:XSubject_Lg), '|') C Remove article number from front of subject line Call ItoS (I, I_C, I_Lg) If (XSubject_Lg .gt. I_Lg) Then XSubject(1:XSubject_Lg-I_Lg) = $ XSubject(1+I_Lg:XSubject_Lg) XSubject_Lg = XSubject_Lg - I_Lg If $ (Subject(1:Subject_Lg) .eq. XSubject(1:XSubject_Lg)) $ Then Status = Range_Find (G, I, .true., U) Call ItoS (I, I_C, I_Lg) Call SMG_All_Print ('Killed: ' // I_C(1:I_Lg), '|') Any = .true. EndIf EndIf ! (XSubject_Lg .gt. I_Lg) EndIf ! (Range_Find(G, I, .false.) .eq. 0) End Do EndIf ! (I_Lg .lt. Subject_Lg) If (.not. Any) Then Call SMG_All_Print ('No articles killed', '|') End If End ! Cmd_ArticleKill Integer Function Cmd_ArticleSameSubj (G, A) Include 'News.Def' C Parameter definition Integer *4 G ! Group number Integer *4 A ! Article number C External routines Integer Range_Find C Local definitions Integer *4 I Integer *4 I_Lg Character *8 I_C Integer *4 Subject_Lg Integer *4 Status Character *128 Subject Integer *4 XSubject_Lg Character *128 XSubject C Begin Cmd_ArticleSameSubj C Send XHdg Subject command to retrieve subject line for article Call CacheHdr (G, A, Subject, Subject_Lg) C Remove article number from front of subject line Call ItoS (A, I_C, I_Lg) If (I_Lg .lt. Subject_Lg) Then Subject(1:Subject_Lg-I_Lg) = Subject(1+I_Lg:Subject_Lg) Subject_Lg = Subject_Lg - I_Lg C Display subject being looked for Call SMG_All_Print $ ('Searching for: ' // Subject(1:Subject_Lg), '|') C Page through articles looking for this subject Do I = Group(G).Active_Start, Group(G).Active_End If (Range_Find(G, I, .false.) .eq. 0) Then Call CacheHdr (G, I, XSubject, XSubject_Lg) C Remove article number from front of subject line Call ItoS (I, I_C, I_Lg) If (XSubject_Lg .gt. I_Lg) Then XSubject(1:XSubject_Lg-I_Lg) = $ XSubject(1+I_Lg:XSubject_Lg) XSubject_Lg = XSubject_Lg - I_Lg If $ (Subject(1:Subject_Lg) .eq. XSubject(1:XSubject_Lg)) $ Then Cmd_ArticleSameSubj = .true. A = I Return EndIf EndIf ! (XSubject_Lg .gt. I_Lg) EndIf ! (Range_Find(G, I, .false.) .eq. 0) End Do EndIf ! (I_Lg .lt. Subject_Lg) Call SMG_All_Print ('No other articles found', '|') Cmd_ArticleSameSubj = .false. Return End ! Cmd_ArticleSameSubj Integer Function Cmd_ArticleFirst (G, A) Include 'News.Def' C Parameter definition Integer *4 G ! Group number Integer *4 A ! Article number C Entry point definitions Integer Cmd_ArticleLast C External routines Integer Range_Find C Local definitions Integer *4 E, D, I, S C Begin Cmd_ArticleFirst S = Group(G).Active_Start E = Group(G).Active_End D = +1 Goto 1 C Begin Cmd_ArticleLast Entry Cmd_ArticleLast (G, A) S = Group(G).Active_End E = Group(G).Active_Start D = -1 Goto 1 C Page through articles looking for first unread 1 Do I = S, E, D If (Range_Find(G, I, .false.) .eq. 0) Then A = I Cmd_ArticleFirst = .true. Return EndIf End Do C No unread articles found Call SMG_All_Print ('No unread articles found', '|') Cmd_ArticleFirst = .false. Return End ! Cmd_ArticleFirst Subroutine XHdr (A, What, Result, Lg) Include 'News.Def' C Parameter definitions Integer *4 A Character *(*) What Character *(*) Result Integer *4 Lg C External routines Integer Srv_Cmd Integer Srv_Recv Integer Srv_RdTxt C local definitions Integer *4 Status C Begin XHdr C Request header line with a 'xhdr what article_number' command Write (Result, '(A,I)') 'xhdr ' // What // ' ', A Status = Srv_Cmd (Result, Result, Lg) If (.not. Status) Then Call SMG_All_Print ('Server failed', '|') Stop EndIf If (Result(1:3) .ne. '221') Then Call SMG_All_Print (Result(1:Lg), '|') Call SMG_All_Print ('Unexpect server response', '|') Stop EndIf C Get header line Status = Srv_Recv (Result, Lg) If (.not. Status) Then Call SMG_All_Print ('Server failed', '|') Stop EndIf C Skip rest of response If (Result(1:Lg) .ne. '.') Then Status = Srv_RdTxt (.false., .false., %Val(0)) If (.not. Status) Then Call SMG_All_Print ('Server failed', '|') Stop EndIf EndIf C Return Return End ! XHdr Subroutine Cmd_Help Include 'News.Def' C Begin Cmd_Help Call SMG_Erase Call SMG_All_Print ('b backup', '|') Call SMG_All_Print ('c [#] catchup', '|') Call SMG_All_Print ('d directory', '|') Call SMG_All_Print ('d/g pattern group directory', '|') Call SMG_All_Print ('f followup', '|') Call SMG_All_Print ('g group go group', '|') Call SMG_All_Print ('h help', '|') Call SMG_All_Print ('k kill', '|') Call SMG_All_Print ('m mark unread', '|') Call SMG_All_Print ('n next', '|') Call SMG_All_Print ('p post', '|') Call SMG_All_Print ('q quit', '|') Call SMG_All_Print ('r refresh', '|') Call SMG_All_Print ('s save', '|') Call SMG_All_Print ('u unsubscribe', '|') Call SMG_All_Print ('x rotate', '|') Call SMG_All_Print ('z next article same subject', '|') Call SMG_All_Print ('# article number', '|') Call SMG_All_Print ('^ first unread article', '|') Call SMG_All_Print ('$ last unread article', '|') Call SMG_All_Print (' ', '|') Return End ! Cmd_Help Integer Function Open_Newsrc () Include 'News.Def' C External routines Integer Range_Allocate Integer TrimLg External User_Open C Local Definitions Character *1 C Integer *4 Status Character *512 Image Integer *4 R Integer *4 S, L, N, E, X C Begin Open_Newsrc Call User_Open_Init ('STATUS_OLD',0,0,0,0,0,0,0,0) Open $ ( $ Unit = LU_Newsrc, $ File = 'Sys$Login:XX.Newsrc', $ Status = 'Old', $ Form = 'Formatted', $ Recl = 512, $ UserOpen = User_Open, $ IOStat = Status $ ) Group_Count = 0 If (Status .ne. 0) Then Newsrc_Is_Open = .false. Open_Newsrc = 0 Return EndIf Newsrc_Is_Open = .true. C Get date of creation of XX.Newsrc Call User_Open_Get_CDT (LU_Newsrc, Newsrc_CDT_VMS) Newsrc_CDT_News(1:2) = Newsrc_CDT_VMS(10:11) ! Year X = Index $ ( $ 'JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC', $ Newsrc_CDT_VMS(4:6) $ ) Write (Newsrc_CDT_News(3:4), '(I2.2)') X/3 + 1 ! Month Newsrc_CDT_News( 5: 6) = Newsrc_CDT_VMS(1:2) ! Day If (Newsrc_CDT_News(5:5) .eq. ' ') Then Newsrc_CDT_News(5:5) = '0' EndIf Newsrc_CDT_News( 7: 7) = ' ' Newsrc_CDT_News( 8: 9) = Newsrc_CDT_VMS(13:14) ! Hour If (Newsrc_CDT_News(8:8) .eq. ' ') Then Newsrc_CDT_News(8:8) = '0' EndIf Newsrc_CDT_News(10:11) = Newsrc_CDT_VMS(16:17) ! Minute If (Newsrc_CDT_News(10:10) .eq. ' ') Then Newsrc_CDT_News(10:10) = '0' EndIf Newsrc_CDT_News(12:13) = Newsrc_CDT_VMS(19:20) ! Second If (Newsrc_CDT_News(12:12) .eq. ' ') Then Newsrc_CDT_News(12:12) = '0' EndIf C Now read users XX.Newsrc Status = 1 Do While (Status) Read $ ( $ Unit = LU_Newsrc, $ Fmt = '(A)', $ IOStat = Status $ ) $ Image If (Status .lt. 0) Then Open_Newsrc = 1 Status = 0 Else If (Status .ne. 0) Then Close (LU_Newsrc) Open_Newsrc = 0 Status = 0 Else Status = 1 X = Index (Image, ':') If (X .eq. 0) Then X = Index (Image, '!') EndIf If (X .ne. 0) Then C We have a new group Group_Count = Group_Count + 1 Group(Group_Count).Range_First = 0 Group(Group_Count).Range_Last = 0 Group(Group_Count).Newsrc_File = .true. C Record group's name Group(Group_Count).Name = Image (1:X-1) C Get subscribed information If (Image(X:X) .eq. ':') Then Group(Group_Count).Subscribed = .true. Else Group(Group_Count).Subscribed = .false. EndIf C Clear moderated and activefile flags, they will get set properly C when we page through the news groups later. Group(Group_Count).Active_Post = .false. Group(Group_Count).Active_File = .false. C Get article ranges S = 0 N = 0 E = 0 L = 0 Do While (X .le. 512) X = X + 1 If (X .eq. 512) Then C = ',' Else C = Image (X:X) EndIf If ((C .ge. '0') .and. (C .le. '9')) Then N = 10 * N + IChar(C) - IChar('0') Else If (C .eq. '-') Then S = N N = 0 Else If (C .eq. ',') Then E = N If (S .eq. 0) Then S = E EndIf C Now add a new range entry to this group's control structure If (S .ne. 0) Then If ((S .le. L) .or. (S .gt. E)) Then Call SMG_All_Print $ ( $ 'Error in XX.Newsrc entry for group ' // $ Group(Group_Count).Name $ (1:TrimLg(Group(Group_Count).Name)), $ '|' $ ) Else R = Range_Allocate () Range(R).Next = 0 Range(R).Start = S Range(R).End = E If (Group(Group_Count).Range_First .eq. 0) Then Group(Group_Count).Range_First = R Else Range(Group(Group_Count).Range_Last).Next $ = R EndIf Group(Group_Count).Range_Last = R L = E EndIf EndIf C Get ready for next range S = 0 E = 0 N = 0 EndIf EndDo Else EndIf EndIf End Do End ! Open_Newsrc Integer Function Close_Newsrc () Include 'News.Def' C External definitions Integer TrimLg C Local Definitions Logical First Integer *4 G Character *512 Image Integer *4 R Integer *4 Status Integer *4 X Integer *4 S, E Character *8 S_C, E_C Integer *4 S_Lg, E_Lg C Begin Close_Newsrc If (Newsrc_Is_Open) Then Close (LU_Newsrc) EndIf Open $ ( $ Unit = LU_Newsrc, $ File = 'Sys$Login:XX.Newsrc', $ Status = 'New', $ Form = 'Formatted', $ CarriageControl = 'List', $ Recl = 512, $ IOStat = Status $ ) G = 1 If (Status .ne. 0) Then Close_Newsrc = 0 Return EndIf C Wander through all groups Do While (G .le. Group_Count) If $ ( $ (Group(G).Active_File .and. Group(G).Subscribed) $ .or. $ Group(G).Newsrc_File $ ) $ Then C Start image with group name X = TrimLg (Group(G).Name) Image(1:X) = Group(G).Name(1:X) C Now add subscribed flag X = X + 1 If (Group(G).Subscribed) Then Image(X:X) = ':' Else Image(X:X) = '!' EndIf C Wander through all ranges for this group R = Group(G).Range_First First = .true. Do While (R .ne. 0) If (.not. First) Then X = X + 1 Image(X:X) = ',' Else First = .false. EndIf S = Range(R).Start Call ItoS (S, S_C, S_Lg) Image(X+1:X+S_Lg) = S_C(1:S_Lg) X = X + S_Lg If (Range(R).End .ne. Range(R).Start) Then X = X + 1 Image(X:X) = '-' E = Range(R).End Call ItoS (E, E_C, E_Lg) Image(X+1:X+E_Lg) = E_C(1:E_Lg) X = X + E_Lg EndIf R = Range(R).Next End Do ! (R .ne. 0) Write (LU_Newsrc, '(A)') Image(1:X) EndIf G = G + 1 End Do ! (G .le. Group_Count) C Return success Close_Newsrc = 1 End ! Close_Newsrc Integer Function Range_Allocate Include 'News.Def' C Begin Range_Allocate If (Range_Free_List .ne. 0) Then Range_Allocate = Range_Free_List Range_Free_List = Range(Range_Free_List).Next Else If (Range_Count .lt. Mx_Range) Then Range_Count = Range_Count + 1 Range_Allocate = Range_Count Else Call SMG_All_Print ('Range array exceeded', '|') Stop EndIf EndIf Range(Range_Allocate).Next = 0 Range(Range_Allocate).Start = 0 Range(Range_Allocate).End = 0 Return End ! Range_Allocate Subroutine Range_Deallocate (R) Include 'News.Def' C Parameter definitions Integer *4 R ! Range index C Local definitions Integer *4 N, X C Begin Range_Deallocate X = R Do While (X .ne. 0) N = Range(X).Next Range(X).Next = Range_Free_List Range_Free_List = X X = N End Do End ! Range_Deallocate Integer Function Range_Find (G, A, Create, U) Include 'News.Def' C Description C C Locates the Range entry for article number A in group G. C If a range entry does not exist for A and Create is true, C one is created. C C Returns the Range entry index or zero if none. C C Parameter definitions Integer *4 G ! Group number Integer *4 A ! Article number Logical Create ! .true. if create on no find Integer *4 U ! Unread article count, updated C External routines Integer Range_Allocate C Local definitions Integer *4 P Integer *4 R, RR Logical Found C Begin Range_Find P = 0 R = Group(G).Range_First Found = .false. Range_Find = 0 Do While ((R .ne. 0) .and. (.not. Found)) If ((A .ge. Range(R).Start) .and. (A .le. Range(R).End)) Then Found = .true. Range_Find = R Else If (A .lt. Range(R).Start) Then Found = .true. Else P = R R = Range(R).Next End If End Do If ((Range_Find .eq. 0) .and. Create) Then If $ ( $ (P .ne. 0) $ .and. $ ((Range(P).End+1) .eq. A) $ ) Then Range(P).End = Range(P).End + 1 Range_Find = P Call Range_Combine (P, R) Else If $ ( $ (R .ne. 0) $ .and. $ ((Range(R).Start-1) .eq. A) $ ) Then Range(R).Start = Range(R).Start - 1 Range_Find = R Call Range_Combine (P, R) Else RR = Range_Allocate () Range_Find = RR Range(RR).Start = A Range(RR).End = A Range(RR).Next = R If (P .eq. 0) Then Group(G).Range_First = Range_Find Group(G).Range_Last = Range_Find Else Range(P).Next = Range_Find EndIf EndIf U = U - 1 If (U .lt. 0) Then U = 0 EndIf EndIf End ! Range_Find Subroutine Range_Combine (P, R) Include 'News.Def' C Parameter definitions Integer *4 P Integer *4 R C Begin Range_Combine If ((P .ne. 0) .and. (R .ne. 0)) Then C Are range entries ajacent? If ((Range(P).End + 1) .eq. Range(R).Start) Then C Mark entry P with entire range Range(P).End = Range(R).End C Remove entry R from the chain Range(P).Next = Range(R).Next C Release entry R Range(R).Next = 0 Call Range_Deallocate (R) EndIf EndIf End ! Range_Combine Integer Function Srv_Connect Include 'News.Def' C Description C C Connects to the Remote News server. C C Returns success or failure. C C Local Variables Integer *4 I Integer *4 Lg Record /Socket_IN_Def/ Server_Socket Integer *4 Status Integer *4 IP_Address Equivalence (IP_Address, Server_IP_Number) C Empty Recv buffer Recv_BufS = 2 Recv_BufE = 1 C Open a channel to INET0: Channel = Socket $ ( $ %Val(AF_INet), $ %Val(Sock_Stream), $ %Val(0) $ ) If (Channel .eq. -1) Then Srv_Connect = 2 Return EndIf C Connect to remote machine Server_Socket.SIN_Family = AF_INet Server_Socket.SIN_Port = HtoNS (%Val(119)) Server_Socket.SIN_Address = IP_Address ! '111e6880'X Do I = 1,8 Server_Socket.SIN_Fill(I) = 0 EndDo Status = Connect $ ( $ %Val(Channel), $ Server_Socket, $ %Val(16) $ ) If (Status .ne. 0) Then Srv_Connect = 4 Return EndIf C Return success Srv_Connect = 1 Return End ! Srv_Connect Integer Function Srv_NetClose() Include 'News.Def' C Description C C Close Connection to the Remote News server. C C Returns success or failure. C C External routines Integer NetClose C Local variables Integer *4 Status C Begin Srv_NetClose C Disconnect from remote machine Status = NetClose (%Val(Channel)) If (Status .ne. 0) Then Srv_NetClose = 4 Return EndIf C Return success Srv_NetClose = 1 Return End ! Srv_NetClose Integer Function Srv_Recv (Buf, Lg) Include 'News.Def' C Description C C Read data form server to Buf. C C Returns success or failure. C Parameter Definitions Character *(*) Buf Integer *4 Lg C Local definitions Integer *4 Buf_Lg Character *2 CRLF Logical CR Logical Done Integer *4 I Integer *4 III Integer *4 N Integer *4 NN Integer *4 Recv_Buf_Addr Integer *4 Recv_Buf_Lg Logical Skip C Begin Srv_Recv Buf_Lg = Len(Buf) CRLF(1:1) = Char(13) CRLF(2:2) = Char(10) Lg = 0 ! No bytes xferred so far Done = .false. CR = .false. Do While (.not. Done) C If there is no data in the receive buffer, get some If (Recv_BufS .gt. Recv_BufE) Then Recv_Buf_Addr = %Loc(Recv_Buf) Recv_Buf_Lg = Len(Recv_Buf) I = Recv $ ( $ %Val(Channel), $ %Val(Recv_Buf_Addr), $ %Val(Recv_Buf_Lg), $ %Val(0) $ ) If (I .eq. -1) Then Srv_Recv = 0 Else Srv_Recv = 1 If (Debug) Then Print '(8(x,o3.3))', (IChar(Recv_Buf(III:III)),III=1,I) EndIf EndIf Recv_BufS = 1 Recv_BufE = I EndIf C Now we have some data C If we last saw a carriage return and the next character is a LF C then we have found the end of the image and we are done If (CR .and. (Recv_Buf(Recv_BufS:Recv_BufS) .eq. CRLF(2:2))) Then Done = .true. Recv_BufS = Recv_BufS + 1 Else C No terminator, look for the next hunk to transfer. CR = .false. I = Index (Recv_Buf(Recv_BufS:Recv_BufE), CRLF(1:1)) If (I .eq. 0) Then N = Recv_BufE - Recv_BufS + 1 Skip = 0 Else N = I - 1 Skip = 1 CR = .true. EndIf C Anything to tranfer? If (N .gt. 0) Then NN = Buf_Lg - Lg If (NN .gt. N) Then NN = N EndIf If (NN .gt. 0) Then Buf(Lg+1:Lg+NN) = Recv_Buf(Recv_BufS:Recv_BufS+NN-1) Lg = Lg + NN EndIf EndIf Recv_BufS = Recv_BufS + N + Skip EndIf EndDo If (Lg .le. 0) Then Lg = 1 Buf(1:1) = ' ' EndIf Return End ! Srv_Recv Integer Function Srv_Send (Msg) Include 'News.Def' C Description C C Send data from Buffer to News Server C C Returns success or failure. C Parameter Definitions Character *(*) Msg C Local definitions Character *512 Buf Integer *4 Buf_Addr Integer *4 Buf_Lg Integer *4 CC C Begin Srv_Send Buf_Lg = Len(Msg) Buf = Msg(1:Buf_Lg) // Char(13) // Char(10) Buf_Addr = %Loc(Buf) Buf_Lg = Buf_Lg+2 CC = Send $ ( $ %Val(Channel), $ %Val(Buf_Addr), $ %Val(Buf_Lg), $ %Val(0) $ ) If (CC .eq. -1) Then Srv_Send = 0 Else Srv_Send = 1 EndIf Return End ! Srv_Send Integer Function Srv_Cmd (Cmd, Rsp, Lg) Include 'News.Def' C Description C C Send Cmd to the news server and retrieve its response in Rsp C C Returns C C Srv_Cmd Success or failure C Rsp Response text from server C Lg Length of Rsp text C Parameter definitions Character *(*) Cmd Character *(*) Rsp Integer *4 Lg C External Routines Integer Srv_Send Integer Srv_Recv C Begin Srv_Cmd Srv_Cmd = Srv_Send (Cmd) If (.not. Srv_Cmd) Then Return EndIf Srv_Cmd = Srv_Recv (Rsp, Lg) C Return Return End ! Srv_Cmd Integer Function Srv_RdTxt (P, Rot, Image_Routine) Include 'News.Def' C Parameters Logical P ! .true. means print ! .false. means skip Logical Rot ! .true. means rotate External Image_Routine ! Called for each image Integer Image_Routine C External Routines Integer Srv_Recv Logical SMG_More_Print C Local definitions Character *512 Buf Integer *4 Lg Logical Ok C Begin Srv_RdTxt Buf(1:1) = ' ' Ok = P Do While (Buf(1:Lg) .ne. '.') Srv_RdTxt = Srv_Recv (Buf, Lg) If (.not. Srv_RdTxt) Then Return EndIf If (Buf(1:Lg) .ne. '.') Then If (Ok) Then If (Rot) Then Call Rotate (Buf(1:Lg)) EndIf If $ ( $ (%Loc(Image_Routine) .eq. 0) $ .or. $ (Image_Routine(Buf(1:Lg))) $ ) $ Then If (Debug) Then Call SMG_More_Print ('RdTxt image:', '|') EndIf OK = SMG_More_Print (Buf(1:Lg), '|') EndIf EndIf EndIf EndDo C All done, return End ! Srv_RdTxt Subroutine Srv_CopyTxt (LU, Pre, Rotate_Flag) Include 'News.Def' C Parameter definitions Integer *4 LU Character *(*) Pre Logical Rotate_Flag C External routines Integer Srv_Recv C Local definitions Character *1024 Buf Integer *4 Buf_S, Buf_E ! Buf pointers Integer *4 Lg Integer *4 MxLg ! Recl for LU_Save Integer *4 Pre_Lg Integer *4 X C Begin Srv_CopyTxt If (Pre .eq. ' ') Then Pre_Lg = 0 Else Pre_Lg = Len (Pre) EndIf Inquire (Unit = LU, Recl = MxLg) MxLg = MxLg - 4 Buf = ' ' Lg = 1 Do While ((Buf(1:Lg) .ne. '.') .and. (Srv_Recv(Buf,Lg))) If (Lg .eq. 0) Then Lg = 1 Buf(1:1) = ' ' EndIf If (Buf(1:lg) .ne. '.') Then If (Rotate_Flag) Then Call Rotate (Buf(1:Lg)) %%end part c Michael Dorl (608) 262-0466 dorl@vms.macc.wisc.edu dorl@wiscmacc.bitnet