home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-12-17 | 26.1 KB | 1,041 lines |
- /*
-
- rn.prg newsreader for Waffle
-
- Release 0.85 by Kafka
-
- */
-
- #include "inkey.ch"
- #include "fileio.ch"
- #include "directry.ch"
- #include "achoice.ch"
- #include "setcurs.ch"
- #include "memoedit.ch"
- #include "marislib.ch"
- #include "rn.ch"
-
- PARAMETER scrsize
- PushDir()
- rnmain(scrsize)
- PopDir()
-
- PROCEDURE rnmain (cScrSize)
-
- LOCAL aGroups := {}
-
-
- setcursor( SC_NONE )
-
- SET DELETED ON
- SET SCOREBOARD OFF
-
- shadowtype(3,8,chr(255) + chr(255) + chr(255)) // set shadow type
-
- readinsert(.t.)
-
- if pcount() > 0
- if cScrSize == "/50"
- setmode(50,80)
- endif
- endif
-
- clear screen
-
- PushVideo()
-
- // get username from the enviroment
- if ! empty(gete("RNUSER"))
- UserName(lower(gete("RNUSER")))
- else
- ask(" Error ", "Environment variable RNUSER not set", {" OK "}, CLR_ERR)
- PopVideo()
- Bye()
- endif
-
- if ! empty(gete("WAFFLE"))
- WafDir(strtran(upper(gete("WAFFLE")), "\STATIC"))
- GotoUserDir()
-
- ScrTitle(" News reader for Waffle ", "RN " + VERSION + " by Kafka │ ", CLR_HDR)
-
- @ 0, 47 say if (empty(FullUserName()), UserName(), left(FullUsername(),20)) color "b/w"
-
- if ! file ((UserDir()+"\RNHIST.DBF"))
- dbcreate((UserDir()+"\RNHIST"), {{"MSGID", "C", 60, 0}})
- endif
-
- use (UserDir()+"\RNHIST") new alias RNHIST
- if ! file(UserDir()+ "\RNHIST.NTX")
- index on lower(RNHIST->MSGID) to (UserDir()+ "\RNHIST")
- else
- set index to (UserDir()+ "\RNHIST")
- endif
-
- aGroups := NwsGrData()
-
- BrowseNewsgroup(1,0,maxrow()-1, maxcol(), aGroups)
-
- else
- ask(" Error ", "Environment variable WAFFLE not set", {" OK "}, CLR_ERR)
- endif
-
- PopVideo()
- RETURN
-
-
-
- FUNCTION ViewMessage( cNewsGroup, a, i, mode )
- LOCAL aHdr := {}
- LOCAL cPath
- LOCAL lReadNew := .f.
- LOCAl nFile
- LOCAL nLines
- LOCAL l
- LOCAL cText := ""
- LOCAL cLine
- LOCAl n
- LOCAl lCont
- LOCAl aKill := GetKillInfo( cNewsgroup )
-
- PRIVATE nLastKey
- PRIVATE aMsg := a
-
- nLastKey := 0
-
- PushVideo()
-
- KeyBar({"PgUp PgDn = Browse", "Esc=quit", "Enter = Next message", "Tab/Space - Next New"}, "n/w")
-
- keyboard(chr(0)) // empty lastkey()
-
- lCont := .t.
- while lCont
-
- cPath := NwsGrPath(cNewsgroup) + "\" + a[i,3]
-
- if ( mode == READ_NEW .and. IsNew(a[i, 4]) ) .or. mode == READ_OLD
-
- aHdr := ReadHeader( cPath )
-
- if (GetKill( aKill, aHdr[MSG_FROM], aHdr[MSG_SUBJ] ) # KILL_OLD .and. mode == READ_NEW) .or. mode == READ_OLD
-
- nFile := fopen(cPath, FO_READ + FO_DENYWRITE )
-
- l := .t.
- nLines := 0
- while ! feof(nFile)
- cLine := freadline(nFile)
- if ! empty(cLine)
- if l
- nLines += mlcount(cLine,80)
- endif
- else
- l := .f.
- exit
- endif
- enddo
-
- fclose(nFile)
- ++nLines
-
- CurrMsg(aHdr, cPath, cNewsgroup)
- nLastKey := 0
-
- dispbegin()
-
- @ 1,0 clear to maxrow()-1, 79
- @ 1,0 say "Newsgroups: "
- @ row(), col() say aHdr[MSG_NWSG] color "w+/n"
-
- @ 2,0 say "From: "
- @ row(), col() say aHdr[MSG_FROM] color "w+/n"
-
- @ 3,0 say "Subject: "
- @ row(), col() say aHdr[MSG_SUBJ] color "w+/n"
-
- @ 4,0 say "Date: "
- @ row(), col() say aHdr[MSG_DATE] color "w+/n"
-
- dispend()
-
- if filesize(cPath) < 65535
- memoedit(memoread(cPath), 6, 0, maxrow()-2,79, .f., "fViewMessage", ,,nLines+1, 0)
- if IsNew(a[i,4])
- MarkAsRead(a[i,4])
- endif
- else
- ask(" View message ", " Sorry can't show message " + cPath + ", size > 64K", {" OK "}, CLR_POP)
- endif
-
- do case
- case nLastKey == 0
- exit
-
- case nLastKey == K_ALT_S
- KillIt(cNewsgroup, aHdr[MSG_SUBJ], KILL_OLD )
-
- case nLastKey == K_ALT_F
- KillIt(cNewsgroup, aHdr[MSG_FROM], KILL_OLD)
-
- case nLastKey == K_ALT_P
- KillIt(cNewsgroup, aHdr[MSG_FROM], KILL_HI)
-
- case nLastKey == K_ALT_H
- KillIt(cNewsgroup, aHdr[MSG_FROM], KILL_HI)
-
- case nLastKey == K_ALT_E
- EditKillFile()
-
- case nLastKey == K_ENTER .or. nLastKey == K_PLUS
- // skip to next message
- mode := READ_OLD
-
- case nLastKey == K_TAB .or. nLastKey == K_SPACE // next new message
- mode := READ_NEW
-
- case nLastKey == K_MINUS
- // skip to previous message
- if i == 1
- i := 0
- sound(3500, 4, 80, 25)
- else
- i -= 2
- endif
- endcase
- endif
- endif
- i++
-
- if i > len(a)
- --i
- exit
- endif
-
- enddo
-
- PopVideo()
- RETURN ( i )
-
-
- FUNCTION fViewMessage (nMode, nLine, nCol)
- LOCAL nRet := 0
- LOCAL nKey := lastkey()
-
- do case
-
- case nMode == ME_UNKEY .or. nMode == ME_UNKEYX .or. nMode == ME_IDLE
- do case
- case nKey == asc("f") // follow-up
- NwsFollow()
- nRet := ME_IGNORE
-
- case nKey == asc("F") // forward article
- NwsForward()
- nRet := ME_IGNORE
-
- case nKey == asc("r") // private reply
- NwsReply(.f.)
- nRet := ME_IGNORE
-
- case nKey == asc("R") // private reply - ask for adressee
- NwsReply(.t.)
- nRet := ME_IGNORE
-
- case nKey == asc("P")
- pmail()
-
- case nKey == asc("p") // post
- NwsPost( CurrMsg()[3], aMsg)
- nRet := ME_IGNORE
-
- case nKey == asc("s") // save article to disk
- NwsSave()
-
- case nKey == asc("C") // cancel article
-
- case nKey == asc("P") // print article
- NwsPrint()
-
- case nKey == asc("!")
- shell()
-
- case nKey == K_ALT_S .or. nKey == K_ALT_F .or. nKey == K_ALT_P ;
- .or. nKey == K_ALT_H .or. nKey == K_ALT_E
-
- nLastKey := nKey
- keyboard chr(K_ESC)
-
- case nKey == K_ESC
- nRet := ME_DEFAULT // quit
-
- case nKey == K_MINUS
- nLastKey := nKey
- keyboard chr(K_ESC)
-
- case nKey == K_ENTER .or. nKey == K_PLUS
- nLastKey := nKey
- keyboard chr(K_ESC)
-
- case nKey == K_TAB .or. nKey == K_SPACE
- nLastKey := K_TAB
- keyboard chr(K_ESC)
-
- endcase
- case nMode == ME_UNKEYX
-
- case nMode == ME_INIT
-
- endcase
- RETURN(nRet)
-
-
- PROCEDURE NwsFollow
- LOCAL aMsg := CurrMsg()
- LOCAL aHeader := aMsg[1]
- LOCAL cPath := aMsg[2]
- LOCAL nMsg
- LOCAL lQuote := .f.
- LOCAL cText := ""
- LOCAL cTmpFile
- LOCAL lSend := .f.
- LOCAL cSubj := ""
- LOCAL nAsk
-
- PushVideo()
- setcursor(SC_NORMAL)
-
- nAsk := Ask(" Follow-up ", " Quote article ?", {" ~Yes ", " ~No "}, CLR_POP)
-
- if nAsk == 1
- lQuote := .t.
- elseif nAsk == 0
- PopVideo()
- RETURN
- endif
-
- nAsk := Ask(" Follow-up ", "Change subject ?", {" ~Yes ", " ~No "}, CLR_POP, 2)
- do case
- case nAsk == 1
- cSubj := GetString(" Change subject ", " Enter new subject ", "(was: " + padr(trim(aHeader[MSG_SUBJ])+ ")",60), , CLR_POP)
- case nAsk == 2
- cSubj := ltrim(aHeader[MSG_SUBJ])
- if left(lower(ltrim(cSubj)),4) == "re: "
- cSubj := substr(cSubj,5)
- endif
- case nAsk == 0
- PopVideo()
- RETURN
- endcase
-
- @ 1,0 clear to maxrow()-1,79
-
- KeyBar({"Esc = Abort", "Ctrl-Enter = Save"}, "n/w")
-
- if lQuote
- nMsg := fopen(cPath, FO_READ + FO_DENYWRITE)
- while ! feof(nMsg) .and. ! empty(freadline(nMsg))
- enddo
-
- cText += "In article " + aHeader[MSG_MSGID] + ", " + From2Name(aHeader[MSG_FROM]) + " writes:" + CR_LF + CR_LF
-
- while ! feof(nMsg)
- cText += upper(left(aHeader[MSG_FROM],2)) + "> " + freadline(nMsg) + CR_LF
- enddo
- fclose( nMsg )
-
- if cText # (cText := Edit(cText, "fNwsFollow"))
- lSend := .t.
- endif
-
- else
- cText := edit(cText, "fNwsFollow")
- if ! empty(cText)
- lSend := .t.
- endif
- endif
-
- if lSend
- cTmpFile := MkTemp()
- cText = MakeHeader(aHeader,"f", cSubj) + hardcr(cText)
- if file(UserDir()+ "\sig")
- cText += CR_LF + CR_LF + memoread(UserDir() + "\sig")
- endif
- memowrit(cTmpFile, cText)
- ScrStat("Posting follow-up in " + if(empty(aHeader[MSG_FUT]), aHeader[MSG_NWSG], aHeader[MSG_FUT]), CLR_HDR)
- swpruncmd("rnews < " + cTmpFile )
- else
- ask(" Follow-up ", " Empty or unedited article not posted", {" OK "}, CLR_POP)
- endif
-
- PopVideo()
- RETURN
-
-
- FUNCTION fNwsFollow (nMode, nLine, nCol)
- LOCAL nRet := 0
- LOCAL nKey := lastkey()
-
- do case
- case nMode == ME_UNKEY .or. nMode == ME_UNKEYX .or. nMode == ME_IDLE
- do case
- case nKey == K_ESC
- if ask(" Edit ", "Abort edit ?", {" ~Yes ", " ~No "}, CLR_POP) == 1
- nRet := ME_DEFAULT // quit
- endif
-
- case nKey == K_CTRL_RET
- if ask(" Edit ", "Send ?", {" ~Yes ", " ~No "}, CLR_POP) == 1
- keyboard chr(K_CTRL_W)
- endif
-
- endcase
-
- case nMode == ME_INIT
-
- endcase
- RETURN(nRet)
-
-
- PROCEDURE NwsReply(lAsk)
- LOCAL aMsg := CurrMsg()
- LOCAL aHeader := aMsg[1]
- LOCAL cPath := aMsg[2]
- LOCAL nMsg
- LOCAL lQuote := .f.
- LOCAL cText := ""
- LOCAL cTmpFile
- LOCAL lSend := .f.
- LOCAL cAdressee
- LOCAL nAsk
-
- PushVideo()
-
- setcursor(SC_NORMAL)
-
- if lAsk
- cAdressee := trim(GetString(" Private reply ", " Enter adressee ", space(40),, CLR_POP))
- if lastkey() == K_ESC
- PopVideo()
- RETURN
- endif
- else
- cAdressee := From2Address(aHeader[MSG_FROM])
- endif
-
-
- nAsk := ask(" Private reply ", " Quote article ?", {" ~Yes ", " ~No "}, CLR_POP)
- if nAsk == 0
- PopVideo()
- RETURN
- elseif nAsk == 1
- lQuote := .t.
- endif
-
- @ 1,0 clear to maxrow()-1,79
-
- KeyBar({"Esc = Abort", "Ctrl-Enter = Save"}, "n/w")
-
- if lQuote
- nMsg := fopen(cPath, FO_READ + FO_DENYWRITE)
-
- while ! feof(nMsg) .and. ! empty(freadline(nMsg))
- enddo
-
- cText += "In article " + aHeader[MSG_MSGID] + ", you write the following:" + CR_LF + CR_LF
- while ! feof(nMsg)
- cText += upper(left(aHeader[MSG_FROM],2)) + "> " + freadline(nMsg) + CR_LF
- enddo
- fclose(nMsg)
-
- if cText # (cText := Edit(cText, "fNwsFollow"))
- lSend := .t.
- endif
-
- else
- cText := Edit("", "fNwsFollow")
- if ! empty(cText)
- lSend := .t.
- endif
- endif
-
- if lSend
- cText = MakeHeader(aHeader,"r",,cAdressee) + hardcr(cText)
- if file(UserDir()+ "\sig")
- cText += CR_LF + CR_LF + memoread(UserDir() + "\sig")
- endif
-
- cTmpFile := MkTemp()
- memowrit(cTmpFile, cText)
- ScrStat("Sending mail to " + cAdressee, CLR_HDR)
-
- swpruncmd("rmail -f" + UserName() ;
- + " " + cAdressee + " < " + cTmpFile )
-
- else
- ask(" Private reply ", " Empty or unedited message not mailed", {" OK "}, CLR_POP)
- endif
-
- PopVideo()
- RETURN
-
-
- PROCEDURE NwsPost(cNwsGrp, a) // Post article
- LOCAL lQuote := .f.
- LOCAL cText := ""
- LOCAL cTmpFile
- LOCAL lSend := .f.
- LOCAL cSubj
- LOCAL cHeader := ""
- LOCAL cCrossPost := space(60)
- LOCAL cFupTo := ""
-
- PushVideo()
- setcursor(SC_NORMAL)
-
- if ask(" Post ", " Post article in " + cNwsGrp + " ?", { " YES ", " NO "}, CLR_POP) == 2 .or. lastkey() == K_ESC
- PopVideo()
- RETURN
- endif
-
- cSubj := GetString(" Post article ", "Enter subject", space(60),, CLR_POP)
-
- if empty(cSubj)
- PopVideo()
- RETURN
- endif
-
- if ask(" Post article ", " Crosspost to other newsgroups ?", {" Yes ", " No " }, CLR_POP, 2) == 1
- cCrossPost := trim(GetString(" Post article ", " Crosspost to (delimited by a comma): ", cCrossPost, , CLR_POP))
- if lastkey() == K_ESC
- PopVideo()
- RETURN
- endif
- endif
-
- if ask(" Post article ", " Enter Follow-up to ?", {" Yes ", " No " }, CLR_POP, 2) == 1
- cFupTo := GetString(" Post article ", "Follow-up to", space(60),, CLR_POP)
- if lastkey() == K_ESC
- PopVideo()
- RETURN
- endif
- endif
-
- @ 1,0 clear to maxrow()-1,79
-
- KeyBar({"Esc = Abort", "Ctrl-Enter = Save"}, "n/w")
-
- cText := Edit("", "fNwsFollow")
- if ! empty(cText)
- lSend := .t.
- endif
-
- if lSend
-
- cTmpFile := MkTemp()
- cHeader += "Path: " + GetStatic("uucpname") + "!" + UserName() + CR_LF
- cHeader += "From: " + UserName() +"@"+ GetStatic("node") + " (" + FullUserName() + ")" + CR_LF
-
- if ! empty(cCrossPost)
- cHeader += "Newsgroups: " + trim(cNwsGrp) + "," + cCrossPost + CR_LF
- else
- cHeader += "Newsgroups: " + trim(cNwsGrp) + CR_LF
- endif
-
- if ! empty(cFupTo)
- cHeader += "Followup-To: " + trim(cFupTo) + CR_LF
- endif
-
-
- cHeader += "Subject: " + trim(cSubj) + CR_LF
- cHeader += "Date: " + left(cdow(date()),3) + ", " + ;
- + str(day(date()),2) + " " ;
- + left(cmonth(date()), 3) + " " ;
- + substr(dtoc(date()), 7,2) + " " ;
- + time() + " ";
- + gete("TZ") + CR_LF
-
- cHeader += "Message-ID: " + MkMsgId() + CR_LF
-
- if cNwsGrp == "alt.hackers"
- cHeader += "Approved: " + "Auto-approved by RN by Kafka@desert.hacktic.nl" + CR_LF
- endif
-
- cHeader += "Organisation: " + GetStatic("organ") + CR_LF + CR_LF
-
- if file(UserDir()+ "\sig")
- cText += CR_LF + CR_LF + memoread(UserDir() + "\sig")
- endif
-
- memowrit(cTmpFile, cHeader + hardcr(cText) )
- // ScrStat("Posting article in " + if(empty(cFupTo), alltrim(cNwsGrp), cFupTo), CLR_HDR)
- ScrStat("Posting article in " + alltrim(cNwsGrp), CLR_HDR)
- swpruncmd("rnews < " + cTmpFile )
- else
- ask(" Post ", " Empty article not posted ", {" OK "}, CLR_POP)
- endif
-
- PopVideo()
-
- RETURN
-
-
- PROCEDURE NwsSave
- LOCAL aMsg := CurrMsg()
- LOCAL aHeader := aMsg[1]
- LOCAL cPath := aMsg[2]
- LOCAL cFile
- LOCAL cSavDir
-
- PushVideo()
- setcursor(SC_NORMAL)
-
- cFile := trim(GetString(" Save article ", "Enter filename", space(60), "@!", CLR_POP))
- if ! empty(cFile)
- chdir(cSavDir)
- ScrStat("Saving article to " + cFile, CLR_HDR)
- fcopy(cPath, cFile)
- chdir(cSavDir)
- endif
-
- PopVideo()
- RETURN
-
-
- FUNCTION NwsPrint()
- LOCAL aMsg := CurrMsg()
- LOCAL aHeader := aMsg[1]
- LOCAL cPath := aMsg[2]
- LOCAL nPrinter := 0
-
- if ask(" View article ", "Print current article ?", { " ~Yes ", " ~No " }, CLR_POP) == 1
- nPrinter := ask(" Print article ", " Print to ", {" LPT1 ", " LPT2 ", " LPT3 "}, "n/w,w/n")
- do case
- case nPrinter == 1
- fcopy(cPath, "LPT1")
- case nPrinter == 2
- fcopy(cPath, "LPT2")
- case nPrinter == 3
- fcopy(cPath, "LPT3")
- otherwise
-
- endcase
- endif
- RETURN(NIL)
-
-
- FUNCTION NwsGrPath(cNwsGrp)
- LOCAL cPath := ""
- LOCAL n
- LOCAL fHandle
- LOCAL c
- LOCAL nPos
- STATIC aPath
-
- if aPath == NIL
- aPath := {}
- endif
-
- nPos := ascan(aPath, {|x| x[1] == cNwsGrp } )
-
- if nPos > 0
- cPath := aPath[nPos, 2]
- else
- fHandle := fopen ( WafDir() + "\usenet", FO_READ + FO_DENYWRITE)
- while ! feof( fHandle )
- c := freadline( fHandle )
- if left(c, 1) # "#"
- if token(c," ",1) == cNwsGrp
- if "/dir=" $ lower(c)
- nPos := at("/dir=", lower(c)) + 5
- cPath := token(substr(c, nPos), " ", 1)
- aadd(aPath, {cNwsGrp, cPath})
- exit
- else
- cPath := NewsDir()
- for n := 1 to numtoken(trim(cNwsGrp), ".")
- cPath += "\" + left(token(trim(cNwsGrp),".", n),8)
- next
- if right(cPath,1) == "\"
- cPath = substr(cPath, 1, len(cPath)-1)
- endif
- aadd(aPath, {cNwsGrp, cPath})
- exit
- endif
- endif
- endif
- enddo
- fClose ( fHandle )
- endif
-
- if empty(cPath)
- ask(" Warning! ", "Joined newsgroup " + cNwsGrp + " isn't contained in '" + WafDir() + "\usenet" + "'",, CLR_ERR )
- endif
- RETURN(cPath)
-
-
- FUNCTION NwsGrData
- STATIC aGroups := {} // array for groups
- LOCAL fHandle
- LOCAL nNewMsg // new messages
- LOCAL nTotMsg
- LOCAL cLine
- LOCAL nJoin
- LOCAl cNwsgr
-
- if len(aGroups) < 1
-
- ScrStat("Retrieving newsgroups information", "*n/w")
-
- if (nJoin := fopen(UserDir() + "\join")) # -1
- while ! feof(nJoin)
-
- cNwsgr := alltrim(token(freadline( nJoin ), " ", 1))
-
- if left(cNwsgr, 1) # "#" .and. ! empty(cNwsgr)
-
- nTotMsg := 0
- nNewMsg := 0
-
- aadd(aGroups, {cNwsgr,{},0,0 })
- fHandle := fopen( NwsGrPath( cNwsgr ) + "\index.rn", FO_READ + FO_DENYWRITE )
-
- while ! feof( fHandle )
- nTotMsg ++
- cLine := freadline( fHandle )
- if IsNew( token(cLine, chr(9), 4))
- nNewMsg++
- endif
- enddo
-
- aGroups[len(aGroups),3] := nTotMsg
- aGroups[len(aGroups),4] := nNewMsg
-
- fclose( fHandle )
-
- endif
- enddo
- else
- ask("Error", "Could not open " + UserDir() + "\join" ,, CLR_ERR)
- quit
- endif
-
- fclose(nJoin )
- endif
-
- RETURN (aGroups)
-
-
- FUNCTION IsNew(cMsgId) // Determines if a message is new or not
- LOCAL lRet
- lRet := RNHIST->(dbseek(lower(alltrim(cMsgId))))
- RETURN (! lRet)
-
-
- FUNCTION UserDir()
- RETURN(GetStatic("user") + "\" + UserName())
-
-
- FUNCTION ImportJoin
- LOCAL nFile, cNg, nMsgNo, n, cLine
-
- dbcreate(UserDir()+"\rnjoin", {{"NG_CODE","N", 5, 0}, {"NG_NAME", "C", 30, 0}})
- dbcreate(UserDir()+"\rnhist", {{"MSGID","C", 60, 0}})
-
- use (UserDir()+"\RNHIST") new alias RNHIST
- index on RNHIST->MSGID to (UserDir()+ "\RNHIST")
-
- use (UserDir()+"\RNJOIN") new alias RNJOIN
- index on lower(RNJOIN->NG_NAME) to (UserDir()+ "\RNJOIN")
-
- if (nFile := fopen(UserDir()+"\JOIN")) == -1
- ask(" Error ", "Could not open" + UserDir()+"\JOIN", {" OK "}, CLR_ERR)
- ? "RTFM!..."
- QUIT
- endif
-
- while ! feof(nFile)
- cLine := freadline(nFile)
- cNg := token(cLine, " ", 1)
- nMsgNo := val(token(cLine, " ", 2))
-
- if ! empty(cNg)
- ScrStat("Adding " + cNg, "n/w")
- RNJOIN->(dbappend())
- replace RNJOIN->NG_NAME with cNg, ;
- RNJOIN->NG_CODE with recno()
- endif
- enddo
-
- fclose(nFile)
-
- RNJOIN->(dbclosearea())
- RNHIST->(dbclosearea())
-
- RETURN(NIL)
-
-
- PROCEDURE Help(cProc)
-
- if cProc == "HELP"
- RETURN
- endif
-
- PushVideo()
-
- setcolor("w+/g")
-
- shadowbox(2,11,21,67, 1, .t.)
- SayCenter(2," Help! ", "gr+/g")
-
- @ 3, 13 say " ! - shell"
- @ 4, 13 say " f - follow up"
- @ 5, 13 say " p - post"
- @ 6, 13 say " r - private reply"
- @ 7, 13 say " R - private reply - ask for addressee"
- @ 8, 13 say " c - catch up (mark whole group as read)"
- @ 9, 13 say " tab/space - next NEW article"
- @ 10, 13 say " return - next article"
- @ 11, 13 say " P - start Pmail"
- @ 12, 13 say " Alt-S - kill subject"
- @ 13, 13 say " Alt-F - kill poster"
- @ 14, 13 say " Alt-P - hilite poster"
- @ 15, 13 say " Alt-H - hilite subject"
- @ 16, 13 say " S - sort article list"
- @ 17, 13 say " s - save article in file "
- @ 18, 13 say " F - forward article "
- saycenter(21, " RN " + VERSION + ", Phreeware 1993 by kafka@desert.hacktic.nl ", "gr+/g")
-
- saycenter(20, "Press the 'any' key", "n/g")
- inkey(0)
-
- PopVideo()
- RETURN
-
-
- PROCEDURE GotoUserDir()
- LOCAL cDir := UserDir()
- setdrive(left(cDir, 2))
- chdir(substr(cDir, 3))
- RETURN
-
-
- FUNCTION Shell
- PushVideo()
- setcursor (SC_NORMAL )
- clear screen
- ? "Type EXIT to return to RN"
- swpruncmd()
- PopVideo()
- RETURN("")
-
-
- PROCEDURE pmail
- PushVideo()
- setcursor(SC_NORMAL)
- swpruncmd("PMAIL")
- PopVideo()
- RETURN
-
-
- PROCEDURE NwsForward
- LOCAL aMsg := CurrMsg()
- LOCAL aHeader := aMsg[1]
- LOCAL cPath := aMsg[2]
- LOCAL cText := ""
- LOCAL cTmpFile
- LOCAL cFwTo := ""
-
- PushVideo()
-
- if Ask(" Forward posting ", " Forward article ?", { " ~Yes ", " ~No " }, CLR_POP) == 1
- cFwTo := trim(GetString(" Forward article ", "Forward article to :", space(60), ,CLR_POP))
- cText += memoread(cPath)
- cTmpFile := MkTemp()
- memowrit(cTmpFile, cText)
- ScrStat("Forwarding message to " + cFwTo, CLR_HDR)
- swpruncmd("rmail -f" + UserName() ;
- + " " + cFwTo + " < " + cTmpFile )
- endif
-
- PopVideo()
- RETURN
-
-
-
- FUNCTION ReadNewsgroup (cNewsgroup, mode )
- LOCAL cPath := NwsGrPath(token(cNewsgroup," ",1))
- LOCAL fHandle
- LOCAL aMsgLst := {}
- LOCAL cLine
- LOCAL aKill := GetKillInfo( cNewsgroup )
-
- if isdir( cPath ) // goto newsgroup's dir
-
- PushVideo()
-
- ScrStat(" Retrieving newsgroup (be patient) ", "*n/w" )
-
- // Read header info into array
-
- fHandle := fopen( cPath + "\index.rn", FO_READ + FO_DENYWRITE )
-
- while ! feof( fHandle )
- cLine := freadline( fHandle )
- AddMsg( aMsgLst, cLine, cNewsgroup )
- enddo
-
- fclose( fHandle )
-
- do case
- case mode == READ_NG_NORMAL
- BrowseMessages( 2, 0, maxrow() -1 , maxcol(), aMsgLst, cNewsgroup )
- case mode == READ_NG_CATCHUP
- Catchup ( aMsgLst )
- endcase
-
- PopVideo()
-
- endif
- RETURN ( aMsgLst)
-
-
-
- FUNCTION GetKillInfo ( cNewsgroup )
- LOCAL aKill := {}
- LOCAL fHandle
- LOCAL cPath := Userdir() + "\" + "kill"
- LOCAL cLine
- LOCAL nPos
-
- if file ( cPath )
- fHandle := fopen( cPath , FO_READ + FO_DENYWRITE )
- while ! feof( fHandle )
- cLine := freadline( fHandle )
- if left( cLine, 1 ) # "#"
- if alltrim(token(cLine, "/", 1)) == alltrim( cNewsgroup ) ;
- .or. alltrim(token(cLine, "/", 1)) == "*"
- aadd(aKill, {})
- nPos := len(aKill)
- aadd(aKill[nPos], lower(token(cLine, "/", 2)))
- aadd(aKill[nPos], token(token(cLine, "/", 3),":", 1))
- aadd(aKill[nPos], lower(token(cLine, ":", 2)))
- endif
- endif
- enddo
- fclose( fHandle )
- endif
-
- RETURN ( aKill )
-
-
- PROCEDURE KillIt( cNewsgroup, cString, Action )
- LOCAL fHandle
- LOCAL cPath := Userdir() + "\" + "kill"
- LOCAL cLine
-
- if ! file ( cPath )
- fHandle := fcreate( cPath , FC_NORMAL)
- fclose( fHandle )
- endif
-
- fHandle := fopen( cPath , FO_READWRITE + FO_DENYWRITE)
-
- FileBottom( fHandle)
-
- cLine := alltrim(cNewsgroup) + "/" + lower(strtran(alltrim(cString), "re:")) + "/h:"
-
- do case
- case Action == KILL_OLD
- cLine += 'j'
- case Action == KILL_HI
- cLine += 'h'
- endcase
-
- fwriteline(fHandle, cLine )
-
- fclose( fHandle )
-
- RETURN
-
-
- FUNCTION GetKill ( aKill, cFrom, cSubj )
- LOCAL n
- LOCAL nRet := KILL_NONE
-
- for n := 1 to len( aKill )
- if aKill[n, 1] $ lower(cFrom + cSubj)
- do case
- case aKill[n,3] == 'm'
- nRet := ( KILL_NEW )
- case aKill[n,3] == 'j'
- nRet := ( KILL_OLD )
- case aKill[n,3] == 'h'
- nRet := ( KILL_HI )
- endcase
- endif
- next
-
- RETURN ( nRet )
-
-
-
- PROCEDURE Catchup( a )
- LOCAL n
- PushVideo()
- ScrStat(" Marking all messages as read ", "n*/w" )
-
- for n := 1 to len(a)
- if IsNew (a[n, 4])
- MarkAsRead(a[n, 4])
- endif
- next
-
- PopVideo()
- RETURN
-
-
- PROCEDURE EditKillFile
- LOCAL cPath := Userdir() + "\" + "kill"
- LOCAL cText
-
- PushVideo()
- setcursor ( SC_NORMAL )
- ScrTitle( "Edit kill file ", "RN " + VERSION + " by Kafka │ " + FullUserName(), CLR_HDR)
- KeyBar({" PgUp PgDn Home End Ctrl-Home Ctrl-End = Browse", "Ctrl-Enter = Save", "Esc = Abort"}, CLR_HDR)
-
- if file ( cPath )
- cText := memoread( cPath )
- else
- cText := ""
- endif
-
- if cText # (cText := Edit(cText, "fEditKill"))
- memowrit ( cPath, cText )
- endif
-
- PopVideo()
- RETURN
-
- FUNCTION fEditKill (nMode, nLine, nCol)
- LOCAL nRet := 0
- LOCAL nKey := lastkey()
-
- do case
- case nMode == ME_UNKEY .or. nMode == ME_UNKEYX .or. nMode == ME_IDLE
- do case
- case nKey == K_ESC
- if ask(" Edit ", "Abort edit ?", {" ~Yes ", " ~No "}, CLR_POP) == 1
- nRet := ME_DEFAULT // quit
- endif
-
- case nKey == K_CTRL_RET
- if ask(" Edit ", "Save ?", {" ~Yes ", " ~No "}, CLR_POP) == 1
- keyboard chr(K_CTRL_W)
- endif
-
- endcase
- endcase
- RETURN( nRet )
-
-