home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 3 Comm / 03-Comm.zip / AUTOPO.ZIP / READBBS.CMD < prev    next >
OS/2 REXX Batch file  |  1991-08-21  |  24KB  |  784 lines

  1. /* REXX to program to READ messages from OS/2 EEP BBS
  2.  
  3.    READBBS 0.07  (c) 1991, University of Missouri
  4.  
  5.    Written by: Rick Wilkeson
  6.                Computer Programmer Analyst II
  7.                Administrative Data Processing
  8.                University of Missouri-Rolla
  9.                   Internet: RICKW@UMRVMB.UMR.EDU
  10.  
  11.  
  12.  
  13.    DISCLAIMER:  This program is distributed "ASIS" no support is given.
  14.    If you locate a bug you can send be a note, but I don't know when I could
  15.    work on fixing it...But you can modify the program yourself.  If you
  16.    do modify this code please give credit where credit is due.  Also, all
  17.    rights are retained by the University of Missouri, so you can't sell it.
  18.  
  19.    I wrote this in a week, so if there are no bugs it will be a miracle.
  20.    Also very little error checking is done.  If you try I'm sure you can
  21.    cause it to crash.
  22.  
  23.    Note:
  24.    Ansi screen routines written by:  Michael J Antonio
  25.                                      (MikeA) 713221.1742@CompuServe.com
  26. */
  27. '@echo off'
  28. Parse Arg params
  29. If params='' | translate(params)='/H' then
  30.    Call Usage
  31. Parse Var params infile .
  32. Call Init
  33. Call Openfile
  34. Call Indexfile
  35. /*  File is open ready to read file */
  36. readpos=stream(infile,'c','seek +0')
  37. say ''
  38. /*  Main conference loop */
  39. curconf=1
  40. do while curconf<=numconf
  41.    if confer.curconf.count>0 then
  42.       do
  43.          Call AnsiSay(color.menuconf)
  44.          say '***' confer.curconf.count '('confer.curconf.minidx'..'confer.curconf.maxidx') messages in' confer.curconf.name
  45.          say 'Read Now? [Y]es, [N]o, [+] next, [-] prev, [Q]uit'
  46.          ch=GetChar()
  47.          select
  48.             when ch='Y'|ch='' then
  49.                do
  50.                   lastmess=false
  51.                   Call ReadConference
  52.                end
  53.             when ch='-' then
  54.                do
  55.                   if curconf>1 then
  56.                      curconf=curconf-1
  57.                   iterate
  58.                end
  59.             when ch='Q' then
  60.                Leave
  61.             when ch='N' | ch='+' then
  62.                nop
  63.          otherwise
  64.             iterate
  65.          end  /* select */
  66.       end
  67.    curconf=curconf+1
  68. end /* do */
  69. Call WriteConfigfile
  70. say
  71. Call AnsiSay(color.attention)
  72. say 'Reading Complete.'||ansi.bblack||ansi.fwhite
  73. Exit
  74.  
  75. /* Get a character from STDIN: */
  76. GetChar: Procedure
  77. ch=strip(Translate(left(LINEIN(),1)))
  78. Return ch
  79.  
  80. /* Get a line from STDIN: */
  81. GetLine: Procedure
  82. input=linein()
  83. Return input
  84.  
  85. /*  Initialize READBBS */
  86. Init:
  87. revision='0.07'
  88. true=1
  89. false=0
  90. 'ANSI ON >nul'
  91. Ansi.=''
  92. Call SetAnsi
  93. /*  Check for command line options */
  94. params=translate(params)
  95. If pos('/I',params)>0 then
  96.    indexflag=true
  97. else
  98.    indexflag=false
  99. If pos('/C',params)>0 then
  100.    Parse Var params '/C' cfgfile
  101. else
  102.    cfgfile=''
  103. If pos('NOLASTREAD',params)>0 | pos('NLR',params)>0 then
  104.    nlrflag=true
  105. else
  106.    nlrflag=false
  107. if cfgfile='' then
  108.    do
  109.       Parse Source os . prgfullname
  110.       pdrive=filespec('drive',prgfullname)
  111.       ppath=filespec('path',prgfullname)
  112.       pfname=filespec('name',prgfullname)
  113.       Parse Var pfname pfilename '.' pext
  114.       cfgfile = pdrive || ppath || pfilename || '.CFG'
  115.    end
  116.  
  117. /* Read Config file */
  118. cfgfile=strip(cfgfile)
  119. rc = stream(cfgfile,'c','query exists')
  120. If rc='' then
  121.    do
  122.       say 'Config file ('cfgfile') not found.'
  123.       exit
  124.    end
  125. rc=stream(cfgfile,'c','open read')
  126. If substr(rc,1,5)<>'READY' then
  127.    do
  128.       say 'Error opening' cfgfile 'for READ.'
  129.       exit
  130.    end
  131. indata = linein(cfgfile)
  132. if substr(indata,1,7)<>'READBBS' then
  133.    do
  134.       say 'Config file ('cfgfile') not in correct format.'
  135.       exit
  136.    end
  137. do while lines(cfgfile)
  138.    select
  139.       when translate(substr(indata,1,12))= 'CONFERENCES:' then
  140.          do
  141.             Parse Upper Var indata 'CONFERENCES:' numconf
  142.             do i = 1 to numconf
  143.                 indata = linein(cfgfile)
  144.                 Parse Var indata confer.i.num confer.i.name '[' confer.i.lastread ']'
  145.                 if confer.i.lastread='' then
  146.                   confer.i.lastread=0
  147.                 confer.i.name=strip(confer.i.name)
  148.              end /* do */
  149.          end
  150.       when translate(substr(indata,1,6))='COLOR:' then
  151.          do
  152.             do i = 1 to 6
  153.                indata=linein(cfgfile)
  154.                Parse Upper Var indata colortype foreground background
  155.                color.fore.colortype=foreground
  156.                color.back.colortype=background
  157.                foreground='f'||strip(foreground)
  158.                background='b'||strip(background)
  159.                interpret 'color.'colortype'=ansi.'foreground'||ansi.'background
  160.             end /* do */
  161.          end /* do */
  162.  
  163.    otherwise
  164.    end /* select */
  165.    indata=linein(cfgfile)
  166. end
  167. rc = stream(cfgfile,'c','close')
  168. numconf=numconf+1
  169. confer.numconf.name  = 'Conference Not Found'
  170. confer.numconf.num = '99'
  171. drive=filespec('drive',infile)
  172. path=filespec('path',infile)
  173. fname=filespec('name',infile)
  174. Parse Var fname filename '.' ext
  175. beginthreadidx=0
  176. cont=1
  177. ch =' '
  178. messidx=0
  179. return
  180.  
  181.  
  182. /* Conference has been selected and ready to read messages */
  183. ReadConference:
  184. messidx=0
  185. if \nlrflag & (confer.curconf.lastread >=confer.curconf.minidx & confer.curconf.lastread <= confer.curconf.maxidx) then
  186.    do
  187.       ch=confer.curconf.lastread+1
  188.       Call FindMessageNumber
  189.    end /* do */
  190. do while cont
  191.    select
  192.       when ch='?' then
  193.          do
  194.             say ' [Number].......Goto closest specified message number.'
  195.             say ' [+], [Return]..Display next message.'
  196.             say ' [-]............Display previous message.'
  197.             say ' [R]............Reply to current message.'
  198.             say ' [T]............Search subject to find next matching message.'
  199.             say ' [S]............Search subject for specified string.'
  200.             say ' [L]............List message number and subject for current conference.'
  201.             say ' [Q]............Quit messages'
  202.             say ' [?]............Display this screen.'
  203.             say
  204.             say '[Return] to return to message.'
  205.             junk=GetChar()
  206.             Call DisplayMessage
  207.          end
  208.       when ch='R' then
  209.          do
  210.             Call ReplyMessage
  211.             call DisplayMessage
  212.          end /* do */
  213.       when ch='T' then
  214.          do
  215.             if beginthreadidx=0 then
  216.                beginthreadidx=messidx
  217.             call SearchThread
  218.             call GetNextMessage
  219.             call DisplayMessage
  220.          end /* do */
  221.       when ch='S' then
  222.          do
  223.             Call SearchSubject
  224.             Call GetNextMessage
  225.             Call DisplayMessage
  226.          end /* do */
  227.       when ch='L' then
  228.          do
  229.             Call ListSubjects
  230.             Call DisplayMessage
  231.          end /* do */
  232.       when datatype(ch)='NUM' then
  233.          do
  234.             say 'Searching for message number' strip(ch)'...'
  235.             beginthreadidx=0
  236.             Call FindMessageNumber
  237.             Call GetNextMessage
  238.             Call DisplayMessage
  239.          end
  240.       when ch='Q' then
  241.          cont=0
  242.       when ch='+' then
  243.          do
  244.             beginthreadidx=0
  245.             if messidx<confer.curconf.count then
  246.                messidx=messidx+1
  247.             Call GetNextMessage
  248.             Call DisplayMessage
  249.          end /* do */
  250.       when ch='-' then
  251.          do
  252.             If messidx<>1 then
  253.                messidx=messidx-1
  254.             beginthreadidx=0
  255.             Call GetNextMessage
  256.             Call DisplayMessage
  257.          end
  258.    otherwise
  259.       do
  260.          if lastmess then
  261.             cont=false
  262.          else
  263.             do
  264.                beginthreadidx=0
  265.                if messidx<confer.curconf.count then
  266.                   messidx=messidx+1
  267.                Call GetNextMessage
  268.                Call DisplayMessage
  269.             end
  270.       end
  271.    end  /* select */
  272.  
  273.    nextline='** Message('mess.curconf.messidx.num') **'
  274.    If lastmess then
  275.       nextline=nextline || color.attention||' Last message in' confer.curconf.name
  276.    Call AnsiSay(color.menumess)
  277.    say nextline
  278.    Call AnsiSay(color.menumess)
  279.    say '['confer.curconf.minidx'..'confer.curconf.maxidx'], [+] or [Return] next, [-] prev'
  280.    say '[R]eply, [T]hread, [S]ubject Search, [L]ist Subjects, [Q]uit, [?] help'
  281.    ch=Translate(GetLine())
  282.    If ch='Q' | (lastmess & ch='') then
  283.       return
  284. end
  285. Return
  286.  
  287. /* Search subject lines for IDENTICAL subject */
  288. SearchThread:
  289. cursubject=mess.curconf.messidx.subject
  290. conf=confer.curconf.name
  291. say 'Searching' strip(conf)'...'
  292. Do i = messidx+1 to confer.curconf.count
  293.    If mess.curconf.i.subject=cursubject then
  294.       do
  295.          messidx=i
  296.          return
  297.       end /* do */
  298. end /* do */
  299. say 'No more message in thread.  Returning to start of thread.'
  300. say '---More---'
  301. ch=GetChar()
  302. rc = stream(infile,'c','seek ='mess.curconf.beginthreadidx.pos)
  303. messidx=beginthreadidx
  304. beginthreadidx=0
  305. return
  306.  
  307. /*  Search Subject lines for phrase */
  308. SearchSubject:
  309. saveidx=messidx
  310. if symbol('srchsubject')='LIT' then
  311.    srchsubject='**No Phrase**'
  312. say 'Enter Phrase to search on: [Return] for "'srchsubject'"'
  313. ssubject=GetLine()
  314. if ssubject<>'' | srchsubject='**No Phrase**' then
  315.    srchsubject=ssubject
  316. srchsubject=translate(srchsubject)
  317. conf=confer.curconf.name
  318. say 'Searching' strip(conf) 'for "'srchsubject'"...'
  319. Do i = messidx+1 to confer.curconf.count
  320.    If pos(srchsubject,translate(mess.curconf.i.subject))<>0 then
  321.       do
  322.          messidx=i
  323.          return
  324.       end /* do */
  325. end /* do */
  326. say 'Subject Phrase Not Found.'
  327. say '---More---'
  328. /*Pull ch*/
  329. ch=GetChar()
  330. rc = stream(infile,'c','seek ='mess.curconf.saveidx.pos)
  331. return
  332.  
  333. FindMessageNumber:
  334. do i=1 to confer.curconf.count while mess.curconf.i.num<ch
  335. end /* do */
  336. If i<=confer.curconf.count then
  337.    do
  338.       messidx=i
  339.       Call GetNextMessage
  340.    end /* do */
  341. else
  342.    do
  343.       say color.attention||'Message number' ch 'not found in' confer.curconf.name'.'
  344.       say 'Press any key to continue.'
  345.       /*pull junk*/
  346.       junk=GetChar()
  347.    end
  348. return
  349.  
  350. GetNextMessage:
  351. rc=stream(infile,'c','seek ='mess.curconf.messidx.pos)
  352. if rc<>mess.curconf.messidx.pos then
  353.    do
  354.       say 'Error in index file.'
  355.       say 'Tried to move to position' mess.messidx.pos'.'
  356.       say 'rc=' rc
  357.       exit
  358.    end /* do */
  359. indata=linein(infile)
  360. do while lines(infile)
  361.    Parse Var indata '****' conf '****'
  362.    if conf<>'' then
  363.       return
  364.    if substr(indata,1,9)='Message :' then
  365.       do
  366.          header.1=indata
  367.          do i=2 to 5
  368.             header.i=linein(infile)
  369.          end /* do */
  370.          i=1
  371.          indata=linein(infile)
  372.          do while lines(infile) & substr(indata,1,9)<>'Message :'
  373.             message.i = indata
  374.             indata=linein(infile)
  375.             i=i+1
  376.          end /* do */
  377.          messagelength=i-1
  378.  
  379.          return
  380.       end /* do */
  381.    indata=linein(infile)
  382. end
  383. return
  384.  
  385. DisplayMessage:
  386. 'cls'
  387. lastmess=false
  388. If mess.curconf.messidx.num=confer.curconf.maxidx then
  389.    lastmess=true
  390. Call AnsiSay(color.header)
  391. do i=1 to 5
  392.    say header.i
  393. end /* do */
  394. Call AnsiSay(color.message)
  395. j=5
  396. do i=1 to messagelength
  397.    if j>21 then
  398.       do
  399.          say '--More-- [Return] to continue, [Q]uit'
  400.          /*PULL ch*/
  401.          ch=GetChar()
  402.          if ch='Q' then
  403.             return
  404.          j=1
  405.       end
  406.    Parse Var message.i '****' mconf '****'
  407.    if mconf <>'' then
  408.       do
  409.          do k=1 to numconf
  410.             if mconf=confer.k.name then
  411.                return
  412.          end /* do */
  413.          say message.i
  414.       end /* do */
  415.    else
  416.       say message.i
  417.    j=j+1
  418. end /* do */
  419. confer.curconf.lastread=mess.curconf.messidx.num
  420. return
  421.  
  422. ListSubjects:
  423. say
  424. say 'Listing Subject for' confer.curconf.name
  425. say
  426. say 'Num  Subject                      From                To'
  427. say copies('-',79)
  428. do i =1 to confer.curconf.count
  429.    if i//21=0 then
  430.       do
  431.          say '---More--- [Return] to continue, [Q]uit'
  432.          /*pull junk*/
  433.          junk=GetChar()
  434.          If junk='Q' then
  435.             return
  436.          say 'Num  Subject                      From                To'
  437.          say copies('-',79)
  438.       end
  439.    lineout=copies(' ',79)
  440.    lineout=overlay(mess.curconf.i.num||'  '||mess.curconf.i.subject,lineout,1)
  441.    lineout=overlay(mess.curconf.i.from,lineout,35)
  442.    lineout=overlay(mess.curconf.i.to,lineout,55)
  443.    say lineout
  444. end /* do */
  445. say 'Press [Return] to return to message.'
  446. /*pull junk*/
  447. junk=GetChar()
  448. return
  449.  
  450. ReplyMessage:
  451. Parse Var header.1 'Message :' replynum .
  452. Parse Var header.2 'From... :' first last .
  453. initials= substr(first,1,1)||substr(last,1,1)
  454. outfile=drive||path||'REP' || strip(replynum) ||'.'||curconf
  455. rc=stream(outfile,'c','query exist')
  456. if rc <>'' then
  457.    do
  458.       'erase' outfile
  459.    end /* do */
  460. rc = stream(outfile,'c','open write')
  461. do i = 1 to messagelength
  462.    outdata = initials||'>'||message.i
  463.    call lineout outfile,outdata
  464. end /* do */
  465. rc = stream(outfile,'c','close')
  466. 'e' outfile
  467. return
  468.  
  469. Openfile:
  470. If infile='' then
  471.    do
  472.       say '*** No mail file specified.***'
  473.       call usage
  474.       exit
  475.    end
  476. rc = stream(infile,'c','query exists')
  477. If rc='' then
  478.    do
  479.       say infile 'does not exist.'
  480.       exit
  481.    end /* do */
  482. fullname = stream(infile,'c','open read')
  483. If substr(fullname,1,5)<>'READY' then
  484.    do
  485.       say 'Error opening' infile
  486.       exit
  487.    end /* do */
  488. return
  489.  
  490. Indexfile:
  491. indexfile=drive||path||filename||'.idx'
  492. indexexists=stream(indexfile,'c','query exists')
  493. If indexexists=''| indexflag then
  494.    do
  495.       Say 'Creating index file...Please wait...'
  496.       Call Reindex
  497.    end /* do */
  498. else
  499.    say 'Reading index file...'
  500. rc=stream(indexfile,'c','close')
  501. rc=stream(indexfile,'c','open read')
  502. Call ReadIndex
  503. rc=stream(indexfile,'c','close')
  504. return
  505.  
  506. ReadIndex:
  507. indata=linein(indexfile)
  508. Parse Var indata prgname prgver ofilesize '-' odatetime
  509. If prgname <>'READBBS' then
  510.    do
  511.       say indexfile 'not in correct format.'
  512.       exit
  513.    end /* do */
  514. filesize=stream(infile,'c','query size')
  515. datetime=stream(infile,'c','query datetime')
  516. if ofilesize <> filesize | datetime <> odatetime then
  517.    do
  518.       say infile 'does not match' indexfile'.  Re-Createing index...'
  519.       Call Reindex
  520.       rc=stream(indexfile,'c','close')
  521.       rc=Stream(indexfile,'c','open read')
  522.       indata=linein(indexfile)
  523.    end
  524. Do i=1 to numconf while lines(indexfile)
  525.    indata=linein(indexfile)
  526.    Parse Var indata '['confer.i.name']['confer.i.count']['confer.i.minidx']['confer.i.maxidx']'
  527.    j=0
  528.    Do k=1 to confer.i.count while lines(indexfile)
  529.       indata=linein(indexfile)
  530.       if substr(indata,1,3)<>'DUP' then
  531.          do
  532.             j=j+1
  533.             Parse Var indata '   ['mess.i.j.pos']['mess.i.j.num']['mess.i.j.subject']['mess.i.j.date']['mess.i.j.to']['mess.i.j.from']'
  534.          end
  535.    end
  536.    confer.i.count=j
  537. end
  538. return
  539.  
  540. reindex:
  541. do i=1 to numconf
  542.    confer.i.maxidx=0
  543.    confer.i.minidx=0
  544.    confer.i.count=0
  545. end /* do */
  546. messcnt=0
  547. say '   Reading Message Headers...'
  548. readpos=stream(infile,'c','seek +0')
  549. datain=linein(infile)
  550. do while lines(infile)
  551.       if substr(datain,1,9)='Message :' then
  552.          do
  553.             header.1=datain
  554.             do i=2 to 4
  555.                header.i=linein(infile)
  556.             end /* do */
  557.             Parse Var header.1 'Message :' mnum  mconf 'Date... :' mdate '(' .
  558.             Parse Var header.2 'From... :' mfrom 'Refer'
  559.             Parse Var header.3 'To..... :' mto "Sec'ty"
  560.             Parse Var header.4 'Subject :' msubject "Rec'vd" .
  561.             mconf=strip(mconf)
  562.             mconf=strip(substr(mconf,2,length(mconf)-2))
  563.             do confcnt=1 to 7 while mconf <> confer.confcnt.name
  564.                nop
  565.             end /* do */
  566.             confer.confcnt.count=confer.confcnt.count+1
  567.             messcnt=confer.confcnt.count
  568.             mess.confcnt.messcnt.num=mnum
  569.             mess.confcnt.messcnt.subject=msubject
  570.             mess.confcnt.messcnt.date = strip(mdate)
  571.             mess.confcnt.messcnt.to = strip(mto)
  572.             mess.confcnt.messcnt.from= strip(mfrom)
  573.             mess.confcnt.messcnt.pos=readpos
  574.             If mess.confcnt.messcnt.num < confer.confcnt.minidx | confer.confcnt.minidx=0 then
  575.                confer.confcnt.minidx=mess.confcnt.messcnt.num
  576.             If mess.confcnt.messcnt.num > confer.confcnt.maxidx | confer.confcnt.maxidx=0 then
  577.                confer.confcnt.maxidx=mess.confcnt.messcnt.num
  578.             DROP header.
  579.          end /* do */
  580.    readpos=stream(infile,'c','seek +0')
  581.    datain=linein(infile)
  582. end /* do */
  583. say '   Sorting Messages...'
  584. Call SortConfers
  585. say '   Writing Index File...'
  586. filesize=stream(infile,'c','query size')
  587. datetime=stream(infile,'c','query datetime')
  588. if indexexists<>'' then
  589.    do
  590.       rc=stream(indexfile,'c','close')
  591.       'del' indexfile
  592.    end
  593. rc=stream(indexfile,'c','open write')
  594. Call lineout indexfile,'READBBS' revision filesize '-' datetime
  595. do i=1 to numconf
  596.    Call lineout indexfile,'['confer.i.name']['confer.i.count']['confer.i.minidx']['confer.i.maxidx']'
  597.    savenum=0
  598.    do j=1 to confer.i.count
  599.       if mess.i.j.num<>savenum then
  600.          do
  601.             Call lineout indexfile,'   ['mess.i.j.pos']['mess.i.j.num']['strip(mess.i.j.subject)']['mess.i.j.date']['mess.i.j.to']['mess.i.j.from']'
  602.             savenum=mess.i.j.num
  603.          end
  604.       else
  605.          do
  606.             Call lineout indexfile, 'DUP['mess.i.j.pos']['mess.i.j.num']['strip(mess.i.j.subject)']['mess.i.j.date']['mess.i.j.to']['mess.i.j.from']'
  607.          end
  608.    end /* do */
  609. end /* do */
  610. DROP mess.
  611. return
  612.  
  613. sortconfers:
  614. do n=1 to numconf
  615.    stackheight=1
  616.    lstack.1=1
  617.    rstack.1=confer.n.count
  618.    do forever
  619.       left=lstack.stackheight
  620.       right=rstack.stackheight
  621.       stackheight=stackheight-1
  622.       do forever
  623.          i=left
  624.          j=right
  625.          a=trunc((left+right)/2)
  626.          median = mess.n.a.num
  627.          do forever
  628.             do while mess.n.i.num < median
  629.                i=i+1
  630.             end /* do */
  631.             do while median < mess.n.j.num
  632.                j=j-1
  633.             end /* do */
  634.             if i<=j then
  635.                do
  636.                   save.num=mess.n.i.num
  637.                   save.pos=mess.n.i.pos
  638.                   save.sub=mess.n.i.subject
  639.                   save.to =mess.n.i.to
  640.                   save.from=mess.n.i.from
  641.                   save.date=mess.n.i.date
  642.                   mess.n.i.num=mess.n.j.num
  643.                   mess.n.i.pos=mess.n.j.pos
  644.                   mess.n.i.subject=mess.n.j.subject
  645.                   mess.n.i.to=mess.n.j.to
  646.                   mess.n.i.from=mess.n.j.from
  647.                   mess.n.i.date=mess.n.j.date
  648.                   mess.n.j.num=save.num
  649.                   mess.n.j.pos=save.pos
  650.                   mess.n.j.subject=save.sub
  651.                   mess.n.j.to=save.to
  652.                   mess.n.j.from=save.from
  653.                   mess.n.j.date=save.date
  654.                   i=i+1
  655.                   j=j-1
  656.                end /* do */
  657.             if i>j then
  658.                leave
  659.          end /* i <= j */
  660.          if i<right then
  661.             do
  662.                stackheight=stackheight+1
  663.                lstack.stackheight=i
  664.                rstack.stackheight=right
  665.             end
  666.          right=j
  667.          if left>=right then
  668.             leave
  669.       end /* left < right  */
  670.       if stackheight=0  then
  671.          leave
  672.    end /* stackheight <> 0 */
  673. end /* do */
  674. drop save.
  675. return
  676.  
  677. WriteConfigFile:
  678. if symbol('confer.1.num')='VAR' then
  679.    do
  680.       'del' cfgfile
  681.       rc=stream(cfgfile,'c','open write')
  682.       numconf=numconf-1
  683.       call lineout cfgfile, 'READBBS' revision
  684.       call lineout cfgfile, 'conferences:' numconf
  685.       do i=1 to numconf
  686.          call lineout cfgfile, confer.i.num confer.i.name '['confer.i.lastread']'
  687.       end /* do */
  688.       call lineout cfgfile,'color:'
  689.       call lineout cfgfile,'  message' color.fore.message color.back.message
  690.       call lineout cfgfile,'  header' color.fore.header color.back.header
  691.       call lineout cfgfile,'  help' color.fore.help color.back.help
  692.       call lineout cfgfile,'  menumess' color.fore.menumess color.back.menumess
  693.       call lineout cfgfile,'  menuconf' color.fore.menuconf color.back.menuconf
  694.       call lineout cfgfile,'  attention' color.fore.attention color.back.attention
  695.    end
  696. else
  697.    say 'Could not update Config file ('cfgfile').'
  698. return
  699.  
  700. Usage:
  701.  
  702. say 'Usage:'
  703. say
  704. say 'READBBS  {text filename} /I /C {config file} NOLASTREAD'
  705. say
  706. say '{text filename} is the "captured" text file from the BBS.'
  707. say '/I tells READBBS to recreate the index file.  Each message file will have an'
  708. say '    index file created for it.'
  709. say
  710. say '/C {config file} tells READBBS to read specified configuration file.  The'
  711. say '    default config filename will be READBBS.CFG (if you renamed READBBS.CMD to'
  712. say '    'something else'.CMD the default will be the 'something else'.CFG)'
  713. say
  714. say 'NOLASTREAD tell READBBS to disregard the last message number read and display'
  715. say '    first message of each conference.  READBBS keeps track of the LARGEST'
  716. say '    message number read for each conference.  If that number is between the'
  717. say '    message numbers for the current conference, READDBBS will automatically'
  718. say '    display the message AFTER the LASTREAD message.'
  719. Exit
  720.  
  721.  
  722. /*************************************************************************
  723.  *
  724.  *  SetAnsi:  Puts the ANSI escape codes and a few usefull constants
  725.  *            in the Ansi. stem variable
  726.  *
  727.  ************************************************************************/
  728. SetAnsi: PROCEDURE EXPOSE Ansi.
  729.    escCd = '1B'x || "["
  730.  
  731.    /** Constants **/
  732.    Ansi.esc = escCd
  733.  
  734.    /* Row and column variables */
  735.    Ansi.rows=25; Ansi.cols=80
  736.    Ansi.row=1;  Ansi.col=1
  737.  
  738.    /* Move charactos - Up, Down, Left, Right */
  739.    Ansi.moveTable = "ABDC"
  740.    Ansi.userTable = '+-<>'
  741.  
  742.    /** Escape codes : NS = Not Supported under OS/2 **/
  743.  
  744.    Ansi.cls    = escCd || "2J"  /* Clears the screen */
  745.    Ansi.erase  = escCd || "K"   /* Erase to End-Of-Line */
  746.  
  747.    /** Screen Attributes:  Used with ScrAttr */
  748.  
  749.    /* Styles */
  750.    Ansi.plain  = escCd || "0m"  /* All attributes off */
  751.    Ansi.bold   = escCd || "1m"  /* Bold type */
  752.    Ansi.faint  = escCd || "2m"  /* Faint type -NS */
  753.    Ansi.italic = escCd || "3m"  /* Italic type */
  754.    Ansi.blink  = escCd || "5m"  /* Blink type */
  755.    Ansi.rblink = escCd || "6m"  /* Rapid-Blink type - NS */
  756.    Ansi.rev    = escCd || "7m"  /* Reverse video */
  757.    Ansi.hidden = escCd || "8m"  /* Concealed type */
  758.    Ansi.subscr = escCd || "48m" /* Subscript */
  759.    Ansi.supscr = escCd || "49m" /* Superscript */
  760.  
  761.    /* Colors, (b)ackground and (f)oreground */
  762.    Ansi.fblack   = escCd || "30m"; Ansi.bblack   = escCd || "40m"
  763.    Ansi.fred     = escCd || "31m"; Ansi.bred     = escCd || "41m"
  764.    Ansi.fgreen   = escCd || "32m"; Ansi.bgreen   = escCd || "42m"
  765.    Ansi.fyellow  = escCd || "33m"; Ansi.byellow  = escCd || "43m"
  766.    Ansi.fblue    = escCd || "34m"; Ansi.bblue    = escCd || "44m"
  767.    Ansi.fmagenta = escCd || "35m"; Ansi.bmagenta = escCd || "45m"
  768.    Ansi.fcyan    = escCd || "36m"; Ansi.bcyan    = escCd || "46m"
  769.    Ansi.fwhite   = escCd || "37m"; Ansi.bwhite   = escCd || "47m"
  770.  
  771.    /* Screen modes 40x25 = 40 X 25, B = Black and White.  C = Color */
  772.    Ansi.40x25B   = escCd || "=0h"; Ansi.40x25C   = escCd || "=1h"
  773.    Ansi.80x25B   = escCd || "=2h"; Ansi.80x25C   = escCd || "=3h"
  774.    Ansi.320x200B = escCd || "=4h"
  775.    Ansi.640x200B = escCd || "=5h"; Ansi.640x200C = escCd || "=6h"
  776.    Ansi.Wrap     = escCd || "=7h"; Ansi.UnWrap   = escCd || "=7I"
  777. RETURN
  778.  
  779.  
  780. AnsiSay: PROCEDURE EXPOSE Ansi.
  781. PARSE ARG attribs
  782. rc = charout(, attribs)
  783. RETURN 0
  784.